1、websocket 统一实现代码
package com.wpg.waterwork.common.websocket;
import lombok.extern.slf4j.Slf4j;
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;
/**
* 类功能描述: webSocket服务层
* 这里我们连接webSocket的时候,路径中传一个参数值id,用来区分不同页面推送不同的数据
*
* @author fxy
* @date 2023-01-09 8:02
*/
@ServerEndpoint(value = "/websocket/{code}")
@Component
@Slf4j
public class WebSocketServer {
/**
* 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
*/
private static int onlineCount = 0;
/**
* concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
*/
public static ConcurrentHashMap<String, WebSocketServer> webSocketSet = new ConcurrentHashMap<>();
/**
* 与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
private Session session;
/**
* 传过来的id
*/
private String id = "0";
/**
* 连接建立成功调用的方法*/
@OnOpen
public void onOpen(@PathParam(value = "code") String param, Session session) {
//接收到发送消息的人员编号
id = param;
this.session = session;
webSocketSet.put(param,this);
addOnlineCount();
log.info("有新连接加入!当前在线人数为" + getOnlineCount());
try {
sendMessage("-连接已建立-");
} catch (IOException e) {
log.error("IO异常");
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
if (id != null && !id.equals("0")) {
webSocketSet.remove(id);
subOnlineCount();
log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
}
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("来自客户端的消息:" + message);
try {
this.sendMessage(message);
} catch (IOException e) {
log.error(e.getMessage());
}
}
/**
* 发生错误时调用
* **/
@OnError
public void onError(Session session, Throwable error) {
log.info("发生错误");
error.printStackTrace();
}
public void sendMessage(String message) throws IOException {
synchronized (session) {
getSession().getBasicRemote().sendText(message);
}
}
public void sendMessage(Object message) throws IOException, EncodeException {
synchronized (session) {
getSession().getBasicRemote().sendObject(message);
}
}
/**
* 给指定的人发送消息
* @param message
*/
public void sendToMessageById(String id,String message) {
try {
if (webSocketSet.get(id) != null) {
webSocketSet.get(id).sendMessage(message);
} else {
log.info("webSocketSet中没有此key,不推送消息");
}
} catch (IOException e) {
log.error(e.getMessage());
}
}
/**
* 群发自定义消息
* */
public static void sendInfo(String message) throws IOException {
for (WebSocketServer item : webSocketSet.values()) {
try {
item.sendMessage(message);
} catch (IOException ignored) {
}
}
}
public Session getSession() {
return session;
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebSocketServer.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebSocketServer.onlineCount--;
}
}
package com.wpg.waterwork.common.websocket;
import lombok.Data;
/**
* 枚举描述: 不同页面区分webSocket
*
* @author fbl
* @date 2019-12-12 09:34
*/
public enum WebSocketEnum {
/**
* 温度传感器
*/
SOCKET_ENUM_TEST("test","测试"),
/**
* 实时报警
*/
SOCKET_ENUM_ALARM("alarm","实时报警");
private String code;
private String msg;
WebSocketEnum(String code,String msg){
this.code = code;
this.msg = msg;
}
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
后端调用代码 应用场景是用户在任意前端点击就会触发,且在多个前端都可以获取响应,此时多个前端监听同一个websocket服务。
@RestController
public class ClickWebSocketController {
@Resource
private WebSocketServer webSocketServer;
@GetMapping("/ClickWebSocket/click")
@ApiOperationSupport(order = 13)
@ApiOperation(value = "点击事件", notes = "点击事件")
public void click(@RequestParam String message, @RequestParam String userId) {
webSocketServer.sendToMessageById("bimAccessClick_" + userId, message);
}
}
前端代码
/**
* 初始化websocket连接
*/
function initWebSocket() {
let uId = 1;
var websocket = null;
if('WebSocket' in window) {
websocket = new WebSocket("ws://10.10.102.221:8877/waterwork-sys-api/websocket/bimAccessClick" );
} else {
alert("该浏览器不支持websocket!");
}
websocket.onopen = function(event) {
console.log("建立连接");
websocket.send('Hello WebSockets!');
}
websocket.onclose = function(event) {
console.log('连接关闭')
reconnect(); //尝试重连websocket
}
//建立通信后,监听到后端的数据传递
websocket.onmessage = function(event) {
let data = JSON.parse(event.data);
//业务处理....
if(data.step == 1){
alert(data.msg);
}
}
websocket.onerror = function() {
// notify.warn("websocket通信发生错误!");
// initWebSocket()
}
window.onbeforeunload = function() {
websocket.close();
}
}
// 重连
function reconnect() {
console.log("正在重连");
// 进行重连
setTimeout(function () {
initWebSocket();
}, 1000);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
<script src="./websocket.js"></script>
<script>
initWebSocket()
</script>
nginx配置
server {
listen 8877;
server_name localhost;
client_max_body_size 100M;
location /waterwork-sys-api/websocket/ {
proxy_pass http://10.10.102.204:8500/waterwork-sys-api/websocket/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}