websocket
This commit is contained in:
@@ -0,0 +1,29 @@
|
|||||||
|
package com.cool.store.request;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: young.yu
|
||||||
|
* @Date: 2023-08-10 19:24
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ApiModel
|
||||||
|
public class CallUpReq {
|
||||||
|
@ApiModelProperty(value = "线索id", required = true)
|
||||||
|
private String lineId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "呼出人用户id", required = true)
|
||||||
|
private String outgoingUserId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "呼出人手机号", required = true)
|
||||||
|
private String outgoingMobile;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "接听人用户id", required = true)
|
||||||
|
private String incomingUserId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "接听人手机号", required = true)
|
||||||
|
private String incomingMobile;
|
||||||
|
}
|
||||||
@@ -85,6 +85,11 @@
|
|||||||
<artifactId>dysmsapi20170525</artifactId>
|
<artifactId>dysmsapi20170525</artifactId>
|
||||||
<version>2.0.1</version>
|
<version>2.0.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!--websocket作为服务端-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
package com.cool.store.handler;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.websocket.*;
|
||||||
|
import javax.websocket.server.PathParam;
|
||||||
|
import javax.websocket.server.ServerEndpoint;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
@ServerEndpoint("/websocket/{tenantId}")
|
||||||
|
public class WebSocketServer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
|
||||||
|
*/
|
||||||
|
private static int onlineCount = 0;
|
||||||
|
/**
|
||||||
|
* concurrent包的线程安全Set,用来存放每个客户端对应的WebSocket对象。
|
||||||
|
*/
|
||||||
|
private static final ConcurrentHashMap<String, WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
|
||||||
|
/**
|
||||||
|
* 与某个客户端的连接会话,需要通过它来给客户端发送数据
|
||||||
|
*/
|
||||||
|
private Session session;
|
||||||
|
/**
|
||||||
|
* 接收userId
|
||||||
|
*/
|
||||||
|
private String tenantId = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接建立成
|
||||||
|
* 功调用的方法
|
||||||
|
*/
|
||||||
|
@OnOpen
|
||||||
|
public void onOpen(Session session, @PathParam("tenantId") String tenantId) {
|
||||||
|
this.session = session;
|
||||||
|
this.tenantId = tenantId;
|
||||||
|
if (webSocketMap.containsKey(tenantId)) {
|
||||||
|
webSocketMap.remove(tenantId);
|
||||||
|
//加入set中
|
||||||
|
webSocketMap.put(tenantId, this);
|
||||||
|
} else {
|
||||||
|
//加入set中
|
||||||
|
webSocketMap.put(tenantId, this);
|
||||||
|
//在线数加1
|
||||||
|
addOnlineCount();
|
||||||
|
}
|
||||||
|
log.info("用户连接:" + tenantId + ",当前在线人数为:" + getOnlineCount());
|
||||||
|
sendMessage("连接成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接关闭
|
||||||
|
* 调用的方法
|
||||||
|
*/
|
||||||
|
@OnClose
|
||||||
|
public void onClose() {
|
||||||
|
if (webSocketMap.containsKey(tenantId)) {
|
||||||
|
webSocketMap.remove(tenantId);
|
||||||
|
//从set中删除
|
||||||
|
subOnlineCount();
|
||||||
|
}
|
||||||
|
log.info("用户退出:" + tenantId + ",当前在线人数为:" + getOnlineCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收到客户端消
|
||||||
|
* 息后调用的方法
|
||||||
|
*
|
||||||
|
* @param message 客户端发送过来的消息
|
||||||
|
**/
|
||||||
|
@OnMessage
|
||||||
|
public void onMessage(String message, Session session) {
|
||||||
|
log.info("用户消息:" + tenantId + ",报文:" + message);
|
||||||
|
//可以群发消息
|
||||||
|
//消息保存到数据库、redis
|
||||||
|
if (StringUtils.isNotBlank(message)) {
|
||||||
|
try {
|
||||||
|
//解析发送的报文
|
||||||
|
JSONObject jsonObject = JSON.parseObject(message);
|
||||||
|
//追加发送人(防止串改)
|
||||||
|
jsonObject.put("fromUserId", this.tenantId);
|
||||||
|
String toUserId = jsonObject.getString("toUserId");
|
||||||
|
//传送给对应toUserId用户的websocket
|
||||||
|
if (StringUtils.isNotBlank(toUserId) && webSocketMap.containsKey(toUserId)) {
|
||||||
|
webSocketMap.get(toUserId).sendMessage(message);
|
||||||
|
} else {
|
||||||
|
//否则不在这个服务器上,发送到mysql或者redis
|
||||||
|
log.error("请求的userId:" + toUserId + "不在该服务器上");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param session Session
|
||||||
|
* @param error Throwable
|
||||||
|
*/
|
||||||
|
@OnError
|
||||||
|
public void onError(Session session, Throwable error) {
|
||||||
|
|
||||||
|
log.error("用户错误:" + this.tenantId + ",原因:" + error.getMessage());
|
||||||
|
error.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实现服务
|
||||||
|
* 器主动推送
|
||||||
|
*/
|
||||||
|
public void sendMessage(String message) {
|
||||||
|
try {
|
||||||
|
this.session.getBasicRemote().sendText(message);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送自定
|
||||||
|
* 义消息
|
||||||
|
**/
|
||||||
|
public static void sendInfo(String message, String tenantId) {
|
||||||
|
log.info("发送消息到:" + tenantId + ",报文:" + message);
|
||||||
|
if (StringUtils.isNotBlank(tenantId) && webSocketMap.containsKey(tenantId)) {
|
||||||
|
webSocketMap.get(tenantId).sendMessage(message);
|
||||||
|
} else {
|
||||||
|
log.error("用户" + tenantId + ",不在线!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得此时的
|
||||||
|
* 在线人数
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public static synchronized int getOnlineCount() {
|
||||||
|
return onlineCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在线人
|
||||||
|
* 数加1
|
||||||
|
*/
|
||||||
|
public static synchronized void addOnlineCount() {
|
||||||
|
WebSocketServer.onlineCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在线人
|
||||||
|
* 数减1
|
||||||
|
*/
|
||||||
|
public static synchronized void subOnlineCount() {
|
||||||
|
WebSocketServer.onlineCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.cool.store.service;
|
||||||
|
|
||||||
|
import com.cool.store.exception.ApiException;
|
||||||
|
import com.cool.store.request.CallUpReq;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: young.yu
|
||||||
|
* @Date: 2023-08-10 18:56
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
public interface CallService {
|
||||||
|
void callUp(CallUpReq request) throws ApiException;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.cool.store.service.impl;
|
||||||
|
|
||||||
|
import com.cool.store.exception.ApiException;
|
||||||
|
import com.cool.store.request.CallUpReq;
|
||||||
|
import com.cool.store.service.CallService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: young.yu
|
||||||
|
* @Date: 2023-08-10 18:58
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class CallServiceImpl implements CallService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void callUp(CallUpReq request) throws ApiException {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,7 +49,9 @@ public class TokenValidateFilter implements Filter {
|
|||||||
//腾讯音视频回调,单独做验签
|
//腾讯音视频回调,单独做验签
|
||||||
"/partner/pc/video/**",
|
"/partner/pc/video/**",
|
||||||
//TODO 800回调地址暂时不做验证
|
//TODO 800回调地址暂时不做验证
|
||||||
"/partner/pc/flow/qualificationReview/callback","/**/ecSync/ecToApplet/**");
|
"/partner/pc/flow/qualificationReview/callback",
|
||||||
|
"/**/ecSync/ecToApplet/**",
|
||||||
|
"/partner/pc/websocket/**");
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.cool.store.controller;
|
||||||
|
|
||||||
|
import com.cool.store.exception.ApiException;
|
||||||
|
import com.cool.store.request.CallUpReq;
|
||||||
|
import com.cool.store.request.GetTipsInfoReq;
|
||||||
|
import com.cool.store.response.ResponseResult;
|
||||||
|
import com.cool.store.service.CallService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: young.yu
|
||||||
|
* @Date: 2023-08-10 18:05
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("call")
|
||||||
|
@Api(tags = "通话")
|
||||||
|
@Slf4j
|
||||||
|
public class CallController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CallService callService;
|
||||||
|
|
||||||
|
@PostMapping("/callUp")
|
||||||
|
@ApiOperation("呼出电话")
|
||||||
|
public ResponseResult callUp(@RequestBody CallUpReq request) throws ApiException {
|
||||||
|
callService.callUp(request);
|
||||||
|
return ResponseResult.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user