电话呼出连接逻辑修改,增加多手机号兼容
This commit is contained in:
@@ -0,0 +1,96 @@
|
|||||||
|
package com.cool.store.utils;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
|
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
**/
|
||||||
|
@Repository
|
||||||
|
public class SpringUtils implements BeanFactoryPostProcessor {
|
||||||
|
|
||||||
|
//Spring应用上下文环境
|
||||||
|
private static ConfigurableListableBeanFactory beanFactory;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||||
|
SpringUtils.beanFactory = beanFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConfigurableListableBeanFactory getBeanFactory() {
|
||||||
|
return beanFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取对象
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return Object 一个以所给名字注册的bean的实例
|
||||||
|
* @throws org.springframework.beans.BeansException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> T getBean(String name) throws BeansException {
|
||||||
|
return (T) getBeanFactory().getBean(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取类型为requiredType的对象
|
||||||
|
*
|
||||||
|
* @param clz
|
||||||
|
* @return
|
||||||
|
* @throws org.springframework.beans.BeansException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static <T> T getBean(Class<T> clz) throws BeansException {
|
||||||
|
T result = (T) getBeanFactory().getBean(clz);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static boolean containsBean(String name) {
|
||||||
|
return getBeanFactory().containsBean(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return boolean
|
||||||
|
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
|
||||||
|
return getBeanFactory().isSingleton(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
* @return Class 注册对象的类型
|
||||||
|
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
|
||||||
|
return getBeanFactory().getType(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果给定的bean名字在bean定义中有别名,则返回这些别名
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return
|
||||||
|
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
|
||||||
|
return getBeanFactory().getAliases(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.cool.store.config.websocket;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
|
||||||
|
|
||||||
|
import javax.websocket.HandshakeResponse;
|
||||||
|
import javax.websocket.server.HandshakeRequest;
|
||||||
|
import javax.websocket.server.ServerEndpointConfig;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class WebSocketConfig extends ServerEndpointConfig.Configurator {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ServerEndpointExporter serverEndpointExporter() {
|
||||||
|
return new ServerEndpointExporter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 建立握手时,连接前的操作
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
|
||||||
|
// 这个userProperties 可以通过 session.getUserProperties()获取
|
||||||
|
final Map<String, Object> userProperties = sec.getUserProperties();
|
||||||
|
Map<String, List<String>> headers = request.getHeaders();
|
||||||
|
List<String> mobiles = headers.get("mobiles");
|
||||||
|
userProperties.put("mobiles", mobiles.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化端点对象,也就是被@ServerEndpoint所标注的对象
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
|
||||||
|
return super.getEndpointInstance(clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,30 @@
|
|||||||
package com.cool.store.handler;
|
package com.cool.store.handler;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.cool.store.config.websocket.WebSocketConfig;
|
||||||
|
import com.cool.store.utils.RedisUtil;
|
||||||
|
import com.cool.store.utils.RedisUtilPool;
|
||||||
|
import com.cool.store.utils.SpringUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import javax.websocket.*;
|
import javax.websocket.*;
|
||||||
import javax.websocket.server.PathParam;
|
import javax.websocket.server.PathParam;
|
||||||
import javax.websocket.server.ServerEndpoint;
|
import javax.websocket.server.ServerEndpoint;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ServerEndpoint("/websocket/{tenantId}")
|
@ServerEndpoint(value="/websocket/{tenantId}",configurator = WebSocketConfig.class)
|
||||||
public class WebSocketServer {
|
public class WebSocketServer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,12 +44,24 @@ public class WebSocketServer {
|
|||||||
*/
|
*/
|
||||||
private String tenantId = "";
|
private String tenantId = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号
|
||||||
|
*/
|
||||||
|
private List<String> mobiles;
|
||||||
|
|
||||||
|
private static RedisUtilPool redisUtilPool = SpringUtils.getBean(RedisUtilPool.class);
|
||||||
/**
|
/**
|
||||||
* 连接建立成
|
* 连接建立成
|
||||||
* 功调用的方法
|
* 功调用的方法
|
||||||
*/
|
*/
|
||||||
@OnOpen
|
@OnOpen
|
||||||
public void onOpen(Session session, @PathParam("tenantId") String tenantId) {
|
public void onOpen(Session session, @PathParam("tenantId") String tenantId) {
|
||||||
|
String mobiles = getHeader(session, "mobiles");
|
||||||
|
if(StringUtils.isEmpty(mobiles)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mobiles = Arrays.asList(mobiles.split(","));
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.tenantId = tenantId;
|
this.tenantId = tenantId;
|
||||||
if (webSocketMap.containsKey(tenantId)) {
|
if (webSocketMap.containsKey(tenantId)) {
|
||||||
@@ -52,6 +74,9 @@ public class WebSocketServer {
|
|||||||
//在线数加1
|
//在线数加1
|
||||||
addOnlineCount();
|
addOnlineCount();
|
||||||
}
|
}
|
||||||
|
for (String mobile : this.mobiles) {
|
||||||
|
redisUtilPool.setString(mobile, tenantId, 3600);
|
||||||
|
}
|
||||||
log.info("用户连接:" + tenantId + ",当前在线人数为:" + getOnlineCount());
|
log.info("用户连接:" + tenantId + ",当前在线人数为:" + getOnlineCount());
|
||||||
sendMessage("连接成功");
|
sendMessage("连接成功");
|
||||||
}
|
}
|
||||||
@@ -177,6 +202,39 @@ public class WebSocketServer {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean isOnline(String tenantId) {
|
public static boolean isOnline(String tenantId) {
|
||||||
|
if(StringUtils.isEmpty(tenantId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return webSocketMap.containsKey(tenantId);
|
return webSocketMap.containsKey(tenantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getHeader(Session session, String headerName) {
|
||||||
|
final String header = (String) session.getUserProperties().get(headerName);
|
||||||
|
if (StrUtil.isBlank(header)) {
|
||||||
|
log.error("获取header失败,不安全的链接,即将关闭");
|
||||||
|
try {
|
||||||
|
session.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getTenantIdByMobile(String mobile){
|
||||||
|
String jsonStr = redisUtilPool.getString(mobile);
|
||||||
|
if (StringUtils.isNotEmpty(jsonStr)){
|
||||||
|
return jsonStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//如果redis中没有,循环webSocketMap,找到对应的tenantId
|
||||||
|
for (String key : webSocketMap.keySet()) {
|
||||||
|
WebSocketServer webSocketServer = webSocketMap.get(key);
|
||||||
|
if (webSocketServer.mobiles.contains(mobile)){
|
||||||
|
return webSocketServer.tenantId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -27,6 +27,7 @@ import com.cool.store.request.CallUpReq;
|
|||||||
import com.cool.store.service.CallService;
|
import com.cool.store.service.CallService;
|
||||||
import com.cool.store.service.LogService;
|
import com.cool.store.service.LogService;
|
||||||
import com.cool.store.utils.CoolDateUtils;
|
import com.cool.store.utils.CoolDateUtils;
|
||||||
|
import com.cool.store.utils.RedisUtilPool;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
@@ -60,8 +61,9 @@ public class CallServiceImpl implements CallService {
|
|||||||
private LogService logService;
|
private LogService logService;
|
||||||
@Override
|
@Override
|
||||||
public String callUp(CallUpReq request) throws ApiException {
|
public String callUp(CallUpReq request) throws ApiException {
|
||||||
|
String tenantId = WebSocketServer.getTenantIdByMobile(request.getOutgoingMobile());
|
||||||
//校验拨出手机号APP是否在线
|
//校验拨出手机号APP是否在线
|
||||||
boolean isOnline = WebSocketServer.isOnline(request.getOutgoingMobile());
|
boolean isOnline = WebSocketServer.isOnline(tenantId);
|
||||||
if (!isOnline) {
|
if (!isOnline) {
|
||||||
throw new ApiException(ErrorCodeEnum.MOBILE_APP_NOT_ONLINE_ERROR);
|
throw new ApiException(ErrorCodeEnum.MOBILE_APP_NOT_ONLINE_ERROR);
|
||||||
}
|
}
|
||||||
@@ -85,7 +87,7 @@ public class CallServiceImpl implements CallService {
|
|||||||
callUpDTO.setTransNo(transNo);
|
callUpDTO.setTransNo(transNo);
|
||||||
callUpDTO.setOutgoingMobile(request.getOutgoingMobile());
|
callUpDTO.setOutgoingMobile(request.getOutgoingMobile());
|
||||||
callUpDTO.setIncomingMobile(request.getIncomingMobile());
|
callUpDTO.setIncomingMobile(request.getIncomingMobile());
|
||||||
boolean sendFlag = WebSocketServer.sendInfo(JSON.toJSONString(callUpDTO), callRecordDO.getOutgoingMobile());
|
boolean sendFlag = WebSocketServer.sendInfo(JSON.toJSONString(callUpDTO), tenantId);
|
||||||
if (!sendFlag) {
|
if (!sendFlag) {
|
||||||
throw new ApiException(ErrorCodeEnum.CREATE_CALL_REQUEST_ERROR);
|
throw new ApiException(ErrorCodeEnum.CREATE_CALL_REQUEST_ERROR);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
package com.cool.store.config;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WebSocket的配置信息
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
public class WebSocketConfig {
|
|
||||||
@Bean
|
|
||||||
public ServerEndpointExporter serverEndpointExporter() {
|
|
||||||
|
|
||||||
return new ServerEndpointExporter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user