Spring Boot 系列

来源:互联网 发布:李兴华java百度云 编辑:程序博客网 时间:2024/05/22 09:40

在实现消息推送的项目中往往需要WebSocket,以下简单讲解在Spring boot 中使用 WebSocket。

1、pom.xml 中引入 spring-boot-starter-websocket

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

2、往spring容器中注入 ServerEndpointExporter

package com.sam.conf;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.server.standard.ServerEndpointExporter;/** * WebSocket配置 * <p> * 自动注册使用了@ServerEndpoint注解声明的Websocket endpoint * 要注意,如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。 * * @author sam * @since 2017/9/13 */@Configurationpublic class WebSocketConfig {    @Bean    public ServerEndpointExporter serverEndpointExporter() {        return new ServerEndpointExporter();    }}

3、Endpoint 具体实现

package com.sam.websocket;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.Map;import java.util.concurrent.ConcurrentHashMap;/** * ServerEndpoint * <p> * 使用springboot的唯一区别是要@Component声明下,而使用独立容器是由容器自己管理websocket的,但在springboot中连容器都是spring管理的。 * <p> * 虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。 * * @author sam * @since 2017/9/13 */@ServerEndpoint("/ws/chatRoom/{userName}") //WebSocket客户端建立连接的地址@Componentpublic class ChatRoomServerEndpoint {    /**     * 存活的session集合(使用线程安全的map保存)     */    private static Map<String, Session> livingSessions = new ConcurrentHashMap<>();    /**     * 建立连接的回调方法     *     * @param session  与客户端的WebSocket连接会话     * @param userName 用户名,WebSocket支持路径参数     */    @OnOpen    public void onOpen(Session session, @PathParam("userName") String userName) {        livingSessions.put(session.getId(), session);        sendMessageToAll(userName + " 加入聊天室");    }    /**     * 收到客户端消息的回调方法     *     * @param message 客户端传过来的消息     * @param session 对应的session     */    @OnMessage    public void onMessage(String message, Session session, @PathParam("userName") String userName) {        sendMessageToAll(userName + " : " + message);    }    /**     * 发生错误的回调方法     *     * @param session     * @param error     */    @OnError    public void onError(Session session, Throwable error) {        System.out.println("发生错误");        error.printStackTrace();    }    /**     * 关闭连接的回调方法     */    @OnClose    public void onClose(Session session, @PathParam("userName") String userName) {        livingSessions.remove(session.getId());        sendMessageToAll(userName + " 退出聊天室");    }    /**     * 单独发送消息     *     * @param session     * @param message     */    public void sendMessage(Session session, String message) {        try {            session.getBasicRemote().sendText(message);        } catch (IOException e) {            e.printStackTrace();        }    }    /**     * 群发消息     *     * @param message     */    public void sendMessageToAll(String message) {        livingSessions.forEach((sessionId, session) -> {            sendMessage(session, message);        });    }}

4、前端页面实现

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>聊天室</title>    <script src="http://code.jquery.com/jquery-1.8.0.min.js"></script></head><body><h1>聊天室</h1><textarea id="chat_content" readonly="readonly" cols="100" rows="9"></textarea><br>用户:<input type="text" id="user_name" value="" name="userName"/><button id="btn_join">加入聊天室</button><button id="btn_exit">退出聊天室</button><br>消息:<input type="text" id="send_text" value="" name="sendText"/><button id="btn_send">发送</button></body></html><script>    $(function () {        var prefixUrl = 'ws://127.0.0.1:8080/ws/chatRoom/';        var ws;//WebSocket连接对象        //判断当前浏览器是否支持WebSocket        if (!('WebSocket' in window)) {            alert('Not support websocket');        }        $('#btn_join').click(function () {            var userName = $('#user_name').val();            //创建WebSocket连接对象            ws = new WebSocket(prefixUrl + userName);            //连接成功建立的回调方法            ws.onopen = function (event) {                console.log('建立连接')            }            //接收到消息的回调方法            ws.onmessage = function (event) {                console.log('接收到内容:' + event.data)                $('#chat_content').append(event.data + '\n')            }            //连接发生错误的回调方法            ws.onerror = function (event) {                console.log('发生错误')            }            //连接关闭的回调方法            ws.onclose = function (event) {                console.log('关闭连接')            }        })        //发送消息        function sendMessage(message) {            ws.send(message);        }        //关闭连接        function closeWebSocket() {            ws.close();        }        //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。        window.onbeforeunload = function () {            wx.close();        }        //发送消息        $('#btn_send').click(function () {            sendMessage($('#send_text').val())        })        //点击退出聊天室        $('#btn_exit').click(function () {            closeWebSocket();        })    })</script>

以上为完整demo内容。

推荐: 阿里技术-小马哥讲解WebSocket
原创粉丝点击