提交 | 用户 | 时间
|
059083
|
1 |
package com.jcdm.main.websocket; |
W |
2 |
|
|
3 |
|
|
4 |
import cn.hutool.log.Log; |
|
5 |
import cn.hutool.log.LogFactory; |
|
6 |
import com.alibaba.fastjson.JSON; |
|
7 |
import com.alibaba.fastjson.JSONObject; |
|
8 |
import org.springframework.stereotype.Component; |
|
9 |
import org.springframework.stereotype.Service; |
|
10 |
import org.springframework.util.StringUtils; |
|
11 |
|
|
12 |
import javax.websocket.*; |
|
13 |
import javax.websocket.server.PathParam; |
|
14 |
import javax.websocket.server.ServerEndpoint; |
|
15 |
import java.io.IOException; |
|
16 |
import java.util.concurrent.ConcurrentHashMap; |
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
@Component |
|
21 |
@Service |
|
22 |
@ServerEndpoint("/websocket/{userId}") |
|
23 |
public class WebSocketServer { |
|
24 |
static Log log = LogFactory.get(WebSocketServer.class); |
|
25 |
/** |
|
26 |
* 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。 |
|
27 |
*/ |
|
28 |
private static int onlineCount = 0; |
|
29 |
/** |
|
30 |
* concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。 |
|
31 |
*/ |
|
32 |
private static ConcurrentHashMap<String, WebSocketServer> webSocketMap = new ConcurrentHashMap<>(); |
|
33 |
/** |
|
34 |
* 与某个客户端的连接会话,需要通过它来给客户端发送数据 |
|
35 |
*/ |
|
36 |
private Session session; |
|
37 |
/** |
|
38 |
* 接收userId |
|
39 |
*/ |
|
40 |
private String userId = ""; |
|
41 |
|
|
42 |
/** |
|
43 |
* 连接建立成功调用的方法 |
|
44 |
*/ |
|
45 |
@OnOpen |
|
46 |
public void onOpen(Session session, @PathParam("userId") String userId) { |
|
47 |
this.session = session; |
|
48 |
this.userId = userId; |
|
49 |
if (webSocketMap.containsKey(userId)) { |
|
50 |
webSocketMap.remove(userId); |
|
51 |
webSocketMap.put(userId, this); |
|
52 |
//加入set中 |
|
53 |
} else { |
|
54 |
webSocketMap.put(userId, this); |
|
55 |
//加入set中 |
|
56 |
addOnlineCount(); |
|
57 |
//在线数加1 |
|
58 |
} |
|
59 |
|
|
60 |
log.info("用户连接:" + userId + ",当前在线人数为:" + getOnlineCount()); |
|
61 |
|
|
62 |
try { |
|
63 |
sendMessage("连接成功"); |
|
64 |
} catch (IOException e) { |
|
65 |
log.error("用户:" + userId + ",网络异常!!!!!!"); |
|
66 |
} |
|
67 |
} |
|
68 |
|
|
69 |
/** |
|
70 |
* 连接关闭调用的方法 |
|
71 |
*/ |
|
72 |
@OnClose |
|
73 |
public void onClose() { |
|
74 |
if (webSocketMap.containsKey(userId)) { |
|
75 |
webSocketMap.remove(userId); |
|
76 |
//从set中删除 |
|
77 |
subOnlineCount(); |
|
78 |
} |
|
79 |
log.info("用户退出:" + userId + ",当前在线人数为:" + getOnlineCount()); |
|
80 |
} |
|
81 |
|
|
82 |
/** |
|
83 |
* 收到客户端消息后调用的方法 |
|
84 |
* |
|
85 |
* @param message 客户端发送过来的消息 |
|
86 |
*/ |
|
87 |
@OnMessage |
|
88 |
public void onMessage(String message, Session session) { |
|
89 |
log.info("用户消息:" + userId + ",报文:" + message); |
|
90 |
//可以群发消息 |
|
91 |
//消息保存到数据库、redis |
|
92 |
|
|
93 |
if (! StringUtils.isEmpty(message)) { |
|
94 |
try { |
|
95 |
//解析发送的报文 |
|
96 |
JSONObject jsonObject = JSON.parseObject(message); |
|
97 |
|
|
98 |
} catch (Exception e) { |
|
99 |
e.printStackTrace(); |
|
100 |
} |
|
101 |
} |
|
102 |
} |
|
103 |
|
|
104 |
/** |
|
105 |
* @param session |
|
106 |
* @param error |
|
107 |
*/ |
|
108 |
@OnError |
|
109 |
public void onError(Session session, Throwable error) { |
|
110 |
log.error("用户错误:" + this.userId + ",原因:" + error.getMessage()); |
|
111 |
error.printStackTrace(); |
|
112 |
} |
|
113 |
|
|
114 |
/** |
|
115 |
* 实现服务器主动推送 |
|
116 |
*/ |
|
117 |
public void sendMessage(String message) throws IOException { |
|
118 |
this.session.getBasicRemote().sendText(message); |
|
119 |
} |
|
120 |
|
|
121 |
|
|
122 |
/** |
|
123 |
* 实现服务器主动推送 |
|
124 |
*/ |
|
125 |
public static void sendAllMessage(String message) throws IOException { |
|
126 |
log.info("发送消息:" + message); |
|
127 |
ConcurrentHashMap.KeySetView<String, WebSocketServer> userIds = webSocketMap.keySet(); |
|
128 |
for (String userId : userIds) { |
|
129 |
WebSocketServer webSocketServer = webSocketMap.get(userId); |
|
130 |
webSocketServer.session.getBasicRemote().sendText(message); |
|
131 |
System.out.println("webSocket实现服务器主动推送成功userIds====" + userIds); |
|
132 |
} |
|
133 |
} |
|
134 |
|
|
135 |
/** |
|
136 |
* 发送自定义消息 |
|
137 |
*/ |
|
138 |
public static void sendInfo(String message, @PathParam("userId") String userId) throws IOException { |
|
139 |
log.info("发送消息到:" + userId + ",报文:" + message); |
|
140 |
if (!StringUtils.isEmpty(message) && webSocketMap.containsKey(userId)) { |
|
141 |
webSocketMap.get(userId).sendMessage(message); |
|
142 |
} else { |
|
143 |
log.error("用户" + userId + ",不在线!"); |
|
144 |
} |
|
145 |
} |
|
146 |
|
|
147 |
public static synchronized int getOnlineCount() { |
|
148 |
return onlineCount; |
|
149 |
} |
|
150 |
|
|
151 |
public static synchronized void addOnlineCount() { |
|
152 |
WebSocketServer.onlineCount++; |
|
153 |
} |
|
154 |
|
|
155 |
public static synchronized void subOnlineCount() { |
|
156 |
WebSocketServer.onlineCount--; |
|
157 |
} |
|
158 |
} |