Browse Source

遗漏代码提交

main
18226920803 1 month ago
parent
commit
8b319817e0
  1. 225
      smart-flow-api/sa-base/src/main/java/net/lab1024/sa/base/config/PhoneWebSocketHandler.java
  2. 36
      smart-flow-api/sa-base/src/main/java/net/lab1024/sa/base/config/WebSocketConfig.java

225
smart-flow-api/sa-base/src/main/java/net/lab1024/sa/base/config/PhoneWebSocketHandler.java

@ -0,0 +1,225 @@
package net.lab1024.sa.base.config;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
/**
* 电话WebSocket处理器
*
* @Author SmartFlow
* @Date 2026-06-09
*/
@Slf4j
@Component
public class PhoneWebSocketHandler extends TextWebSocketHandler {
/**
* 存储所有在线的WebSocket会话key为坐席IDvalue为会话
*/
private static final ConcurrentHashMap<String, WebSocketSession> SESSION_MAP = new ConcurrentHashMap<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
String agentId = getAgentId(session);
if (agentId != null) {
SESSION_MAP.put(agentId, session);
log.info("坐席 {} WebSocket连接已建立,当前在线坐席数: {}", agentId, SESSION_MAP.size());
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
String agentId = getAgentId(session);
if (agentId != null) {
SESSION_MAP.remove(agentId);
log.info("坐席 {} WebSocket连接已关闭,当前在线坐席数: {}", agentId, SESSION_MAP.size());
}
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String payload = message.getPayload();
log.info("收到WebSocket消息: {}", payload);
// 可以在这里处理客户端发送的消息
// 例如:坐席状态更新、接听/挂断操作等
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
log.error("WebSocket传输异常", exception);
String agentId = getAgentId(session);
if (agentId != null) {
SESSION_MAP.remove(agentId);
}
}
/**
* 向指定坐席发送消息
*
* @param agentId 坐席ID
* @param message 消息内容
*/
public void sendMessageToAgent(String agentId, String message) {
WebSocketSession session = SESSION_MAP.get(agentId);
if (session != null && session.isOpen()) {
try {
session.sendMessage(new TextMessage(message));
log.info("向坐席 {} 发送消息成功", agentId);
} catch (IOException e) {
log.error("向坐席 {} 发送消息失败", agentId, e);
}
} else {
log.warn("坐席 {} 不在线或会话已关闭", agentId);
}
}
/**
* 向所有在线坐席广播消息
*
* @param message 消息内容
*/
public void broadcastToAll(String message) {
SESSION_MAP.forEach((agentId, session) -> {
if (session.isOpen()) {
try {
session.sendMessage(new TextMessage(message));
} catch (IOException e) {
log.error("向坐席 {} 广播消息失败", agentId, e);
}
}
});
}
/**
* 发送来电弹屏消息
*
* @param agentId 坐席ID
* @param callerInfo 来电信息
*/
public void sendIncomingCall(String agentId, Object callerInfo) {
String message = JSON.toJSONString(new IncomingCallMessage(
"INCOMING_CALL",
callerInfo,
System.currentTimeMillis()
));
sendMessageToAgent(agentId, message);
}
/**
* 发送挂断消息
*
* @param agentId 坐席ID
* @param callId 通话ID
*/
public void sendCallEnded(String agentId, String callId) {
String message = JSON.toJSONString(new CallEndedMessage(
"CALL_ENDED",
callId,
System.currentTimeMillis()
));
sendMessageToAgent(agentId, message);
}
/**
* 从会话中获取坐席ID
*/
private String getAgentId(WebSocketSession session) {
String query = session.getUri() != null ? session.getUri().getQuery() : null;
if (query != null) {
String[] params = query.split("&");
for (String param : params) {
if (param.startsWith("agentId=")) {
return param.substring("agentId=".length());
}
}
}
return null;
}
/**
* 来电消息
*/
public static class IncomingCallMessage {
private String type;
private Object data;
private long timestamp;
public IncomingCallMessage(String type, Object data, long timestamp) {
this.type = type;
this.data = data;
this.timestamp = timestamp;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
}
/**
* 通话结束消息
*/
public static class CallEndedMessage {
private String type;
private String callId;
private long timestamp;
public CallEndedMessage(String type, String callId, long timestamp) {
this.type = type;
this.callId = callId;
this.timestamp = timestamp;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCallId() {
return callId;
}
public void setCallId(String callId) {
this.callId = callId;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
}
}

36
smart-flow-api/sa-base/src/main/java/net/lab1024/sa/base/config/WebSocketConfig.java

@ -0,0 +1,36 @@
package net.lab1024.sa.base.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* WebSocket配置类
*
* @Author SmartFlow
* @Date 2026-06-09
*/
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// 注册WebSocket处理器,允许跨域访问
registry.addHandler(phoneWebSocketHandler(), "/websocket/phone")
.setAllowedOrigins("*");
}
@Bean
public PhoneWebSocketHandler phoneWebSocketHandler() {
return new PhoneWebSocketHandler();
}
}
Loading…
Cancel
Save