SpringBoot学习-(十二)SpringBoot中建立WebSocket连接

来源:互联网 发布:交换机端口号怎么看 编辑:程序博客网 时间:2024/06/05 18:57

WebSocket握手图解:

这里写图片描述

建立连接的步骤:

  • pom文件中添加依赖
  • 创建握手拦截器
  • 创建WebSocket处理类
  • 配置WebSocket
  • 前端页面访问

项目目录结构:
这里写图片描述

1.pom文件中添加依赖

<!-- springboot websocket --><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-websocket</artifactId></dependency>

2.创建握手拦截器

用于进行握手之前和握手之后的操作
一般用于握手之前将用户信息交给WebSocketSession管理
之后可以在WebSocket处理类中获取用户信息

package com.ahut.websocket;import java.util.Map;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.http.server.ServerHttpRequest;import org.springframework.http.server.ServerHttpResponse;import org.springframework.http.server.ServletServerHttpRequest;import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.server.HandshakeInterceptor;/** *  * @ClassName: MyWebSocketInterceptor * @Description: 创建握手 此类用来获取登录用户信息并交由websocket管理 * @author cheng * @date 2017年9月26日 上午10:31:30 *//** * HandshakeInterceptor WebSocket握手请求的拦截器. 检查握手请求和响应, 对WebSocketHandler传递属性 */public class MyWebSocketInterceptor implements HandshakeInterceptor {    private Logger logger = LoggerFactory.getLogger(this.getClass());    /**     * 在握手之前执行该方法, 继续握手返回true, 中断握手返回false. 通过attributes参数设置WebSocketSession的属性     */    @Override    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,            Map<String, Object> attributes) throws Exception {        logger.info("xxx用户建立连接。。。");        if (request instanceof ServletServerHttpRequest) {            String userId = ((ServletServerHttpRequest) request).getServletRequest().getParameter("userId");            attributes.put("userId", userId);            logger.info("用户唯一标识:" + userId);        }        return true;    }    /**     * 在握手之后执行该方法. 无论是否握手成功都指明了响应状态码和相应头.     */    @Override    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,            Exception exception) {    }}

3.创建WebSocket处理类

处理类的层级关系:
这里写图片描述

package com.ahut.websocket;import java.util.ArrayList;import java.util.List;import java.util.Map;import org.slf4j.Logger;import org.slf4j.LoggerFactory;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;/** *  * @ClassName: WebSocketPushHandler * @Description: 创建处理器 * @author cheng * @date 2017年9月26日 上午10:36:17 */public class WebSocketPushHandler extends TextWebSocketHandler {    private Logger logger = LoggerFactory.getLogger(this.getClass());    private static final List<WebSocketSession> userList = new ArrayList<>();    /**     * 用户进入系统监听     */    @Override    public void afterConnectionEstablished(WebSocketSession session) throws Exception {        logger.info("xxx用户进入系统。。。");        logger.info("用户信息:" + session.getAttributes());        Map<String, Object> map = session.getAttributes();        for (String key : map.keySet()) {            logger.info("key:" + key + " and value:" + map.get(key));        }        userList.add(session);    }    /**     * 处理用户请求     */    @Override    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {        logger.info("系统处理xxx用户的请求信息。。。");    }    /**     * 用户退出后的处理     */    @Override    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {        if (session.isOpen()) {            session.close();        }        userList.remove(session);        logger.info("xxx用户退出系统。。。");    }    /**     * 自定义函数      * 给所有的在线用户发送消息     */    public void sendMessagesToUsers(TextMessage message) {        for (WebSocketSession user : userList) {            try {                // isOpen()在线就发送                if (user.isOpen()) {                    user.sendMessage(message);                }            } catch (IOException e) {                e.printStackTrace();                logger.error(e.getLocalizedMessage());            }        }    }    /**     * 自定义函数      * 发送消息给指定的在线用户     */    public void sendMessageToUser(String userId, TextMessage message) {        for (WebSocketSession user : userList) {            if (user.getAttributes().get("userId").equals(userId)) {                try {                    // isOpen()在线就发送                    if (user.isOpen()) {                        user.sendMessage(message);                    }                } catch (IOException e) {                    e.printStackTrace();                    logger.error(e.getLocalizedMessage());                }            }        }    }}

4.配置WebSocket

package com.ahut.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.WebSocketHandler;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.HandshakeInterceptor;import com.ahut.websocket.MyWebSocketInterceptor;import com.ahut.websocket.WebSocketPushHandler;/** *  * @ClassName: WebSocketConfig * @Description: websocket配置类 * @author cheng * @date 2017年9月26日 上午10:45:45 */@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer {    /**     * 注册WebSocket处理类     */    @Override    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {        registry.addHandler(createWebSocketPushHandler(), "/webSocketServer")                .addInterceptors(createHhandshakeInterceptor()).setAllowedOrigins("*");        registry.addHandler(createWebSocketPushHandler(), "/sockjs/webSocketServer")                .addInterceptors(createHhandshakeInterceptor()).withSockJS();    }    /**     *      * @Title: createHhandshakeInterceptor     * @Description: 握手拦截器     * @return     */    @Bean    public HandshakeInterceptor createHhandshakeInterceptor() {        return new MyWebSocketInterceptor();    }    /**     *      * @Title: createWebSocketPushHandler     * @Description: 处理类     * @return     */    @Bean    public WebSocketHandler createWebSocketPushHandler() {        return new WebSocketPushHandler();    }}

5.前端页面访问

<!DOCTYPE html><html><head><title>Java后端WebSocket的Tomcat实现</title></head> <body>      Welcome<br/><input id="text" type="text"/>      <button onclick="send()">发送消息</button>     <hr/>     <button onclick="closeWebSocket()">关闭WebSocket连接</button>     <hr/>     <div id="message"></div> </body> <script type="text/javascript">     var websocket = null;     //判断当前浏览器是否支持WebSocket    if ('WebSocket' in window) {        websocket = new WebSocket("ws://localhost:8080/webSocketServer?userId=wrwefesdfwetrwe324324");    }     else {         alert('当前浏览器 Not support websocket')     }     //连接发生错误的回调方法     websocket.onerror = function () {         setMessageInnerHTML("WebSocket连接发生错误");     };     //连接成功建立的回调方法     websocket.onopen = function () {         setMessageInnerHTML("WebSocket连接成功");     }     //接收到消息的回调方法     websocket.onmessage = function (event) {         setMessageInnerHTML(event.data);     }     //连接关闭的回调方法     websocket.onclose = function () {         setMessageInnerHTML("WebSocket连接关闭");     }     //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。     window.onbeforeunload = function () {         closeWebSocket();     }     //将消息显示在网页上     function setMessageInnerHTML(innerHTML) {         document.getElementById('message').innerHTML += innerHTML + '<br/>';     }     //关闭WebSocket连接     function closeWebSocket() {         websocket.close();     }     //发送消息     function send() {         var message = document.getElementById('text').value;         websocket.send(message);     } </script> </html>

打开页面后台日志打印结果:

这里写图片描述

阅读全文
0 0
原创粉丝点击