赞
踩
在配置类中一般需要实现“注册WebSocket处理程序”、“Bean注册”。
-
- @Configuration
- @EnableWebSocket//启用WebSocket功能
- public class WebSocketConfig implements WebSocketConfigurer {
-
- @Override
- public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
- registry.addHandler(myWebSocketHandler(), "/chat")
- //将WebSocket处理程序注册到指定的路径
- .addInterceptors(new HandshakeInterceptor() {
- public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
- ServletServerHttpRequest request = (ServletServerHttpRequest)serverHttpRequest;
- String username = request.getServletRequest().getParameter("username");
- map.put("username", username);
- return true;
- }//从 HTTP 请求中获取用户名,并将其添加到 WebSocket 握手中的属性 Map 中
-
- });
- }
-
- @Bean
- public WebSocketHandler myWebSocketHandler() {
- return new MyWebSocketHandler();
- //创建了一个 WebSocket 处理程序的实例并将其作为 bean 注册到 Spring 上下文中。
- //这将使处理程序在需要时自动注入到其他组件中
- }
-
-
- }
-
-
上面的代码首先注册了自定义的 WebSocket 处理程序。在自定义的WebSocket的处理程序中指定了客户端连接的路径;并添加了一个握手拦截器,用来获取HTTP请求的用户名,并将其添加到WebSocket握手中的Map属性中,以便WebSocketHandler 可以通过读取属性映射中的值来访问和使用这些信息。
其次创建了一个 WebSocket 处理程序的实例并将其作为 bean 注册到 Spring 上下文中
在正式的处理逻辑中,一般需要实现"连接成功时的逻辑"、"连接失败时的逻辑"、“连接关闭的逻辑”。
- public class MyWebSocketHandler implements WebSocketHandler {
- //保存所有在线用户的session的集合容器
- private static CopyOnWriteArrayList<WebSocketSession> sessions =
- new CopyOnWriteArrayList<>();
- //保存所有在线用户
- private static CopyOnWriteArrayList<String> usernames =
- new CopyOnWriteArrayList<>();
- ObjectMapper om = new ObjectMapper();//Java 对象和 JSON 数据之间进行序列化和反序列化。
- @Override
- public void afterConnectionEstablished(WebSocketSession session) throws Exception {
- // 连接成功时的逻辑
- //保存连接的这个人的session和用户名
- Map<String, Object> attributes = session.getAttributes();
- String username = (String) attributes.get("username");
- usernames.add(username);
- sessions.add(session);
- //发送一个谁谁谁上线了的消息给所有人
- Chat chat = new Chat(username,"上线了",1);
- String jsonStr = om.writeValueAsString(chat);
- //转发数据给所有人
- sendAll(jsonStr);
- //发送所有用户在线列表
- jsonStr = om.writeValueAsString(usernames);
- sendAll(jsonStr);
-
- }
- //向所有已连接websocket的客户端发消息
- private void sendAll(String jsonStr) throws IOException{
- for(WebSocketSession session: sessions){
- if(session.isOpen()){
- session.sendMessage(new TextMessage(jsonStr));
- }
- }
- }
-
- @Override
- public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
- // 处理消息的逻辑
- String username = (String) session.getAttributes().get("username");
- Chat msg = null;
-
- // 处理文本消息
- String msgStr = message.getPayload().toString();
- if("\0".equals(msgStr)){
- msg =new Chat(username,"发送了一个窗口抖动",5);
- }else if (msgStr.startsWith("\1")){
- String messageId = msgStr.substring(1);//从第一个位置开始截取,第0个位置是\1
- msg = new Chat(username,"撤回了一条消息",6,messageId);
- }else{
- String msgT = msgStr.substring(1);
- msg = new Chat(username,msgT,4, UUID.randomUUID().toString());
- System.out.println("文本消息");
- System.out.println(msgT);
- }
-
- String jsonStr = om.writeValueAsString(msg);
- sendAll(jsonStr);
- }
-
- @Override
- public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
- // 处理连接失败时的逻辑
- }
-
- @Override
- public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
- // 连接关闭时的逻辑
- String username = (String) session.getAttributes().get("username");
- //移除这个session
- sessions.remove(session);
- usernames.remove(username);
- Chat message = new Chat("系统消息",username+"下线了",1);
- String jsonStr = om.writeValueAsString(message);
- sendAll(jsonStr);
- jsonStr = om.writeValueAsString(usernames);
- sendAll(jsonStr);
- }
-
- }
上面的代码中:
1)连接成功的逻辑;首先保存了连接WebSocket服务器客户端的session以及用户名;然后将用户上线消息广播到了连接这个WebSocket服务器的所有客户端;并且刷新群聊用户在线用户列表。
其次定义了客户端如何与WebSocket交互的逻辑,识别传输消息的第一个字符,做出相应包装处理,广播给所有客户端
2)连接失败的逻辑;未定义
3)连接关闭的逻辑;移除客户端session以及将用户名从用户列表中删除并发送下线消息。
另外将消息广播到所有连接客户端的逻辑独立出来复用
在js代码中,同样应该首先向WebSocket服务器建立逻辑,然后再定义“连接成功的逻辑”、“连接失败的逻辑”、“连接关闭的逻辑”。
- var username = $("#username").val();
- //window.location.host代表获取ip:port
- var url = "ws://" + window.location.host + "/chat?username=" + username;
- //与后台建立websocket长连接
- // alert(url);
- var ws = new WebSocket(url);
- ws.onopen = function () {
- //处理成功时的逻辑
- console.log("成功")
- };
- ws.onmessage = function (e) {
- //处理消息的逻辑
- var message = JSON.parse(e.data);
- console.log("成功+1")
- //alert(message.type);
- //alert(message.content);
- if (!message.type){
- onlineUser(message);
- }else if (message.type == 1) {
- //系统上线消息
- systemOnlineMessage(message);
- }else if(message.type == 4){
- //用户文本消息
- userTextMessage(message);
- }else if(message.type == 5){
- // 收到用户抖动消息
- dydMessage(message);
- }else if(message.type == 6){
- //用户撤销消息
- withdrawMessage(message);
- }else if(message.type == 7){
- userImageMessage(message);
- }
- ws.onclose = function(event) {
- // 连接关闭时的逻辑
- }
- /*滚动条滑到最底部*/
- $("#record").scrollTop(9999999);
- };
具体函数实现代码未给出,代码使了的jquery库
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。