SpringBoot整合WebSocket

WebSocket协议是一种全双工协议,服务端可以主动向客户端推送消息,可以是文本也可以是二进制数据,而且没有同源策略的限制,不存在跨域问题。这里主要介绍服务端向客户端推送消息。

第一步:导入依赖

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>sockjs-client</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>stomp-websocket</artifactId>
            <version>2.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.3.1</version>
        </dependency>

第二步:创建WebSocket进行消息的推送

package com.example.websocket.controller;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @Author: yushizhong
 * @Date: 2020/1/10 15:42
 * @Title: 描述
 */
@Component
@ServerEndpoint(value = "/ws/myWebSocket")
public class WebSocket {

    //每个客户端都会有相应的session,服务端可以发送相关消息
    private Session session;

    //J.U.C包下线程安全的类,主要用来存放每个客户端对应的webSocket连接,为什么说他线程安全。在文末做简单介绍
    private static CopyOnWriteArraySet<WebSocket> copyOnWriteArraySet = new CopyOnWriteArraySet<WebSocket>();

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

    /**
     * 打开连接。进入页面后会自动发请求到此进行连接
     * @param session
     */
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        copyOnWriteArraySet.add(this);
        System.out.println("websocket有新的连接, 总数:"+ copyOnWriteArraySet.size());

    }

    /**
     * 用户关闭页面,即关闭连接
     */
    @OnClose
    public void onClose() {
        copyOnWriteArraySet.remove(this);
        System.out.println("websocket连接断开, 总数:"+ copyOnWriteArraySet.size());
    }

    /**
     * 测试客户端发送消息,测试是否联通
     * @param message
     */
    @OnMessage
    public void onMessage(String message) {
        System.out.println("websocket收到客户端发来的消息:"+message);
        sendMessage(message);
    }


    /**
     * 出现错误
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误:" + error.getMessage()+session.getId());
        error.printStackTrace();
    }

    /**
     * 用于发送给客户端消息(群发)
     * @param message
     */

    public void sendMessage(String message) {


        //遍历客户端
        for (WebSocket webSocket : copyOnWriteArraySet) {
            System.out.println("websocket广播消息:" + message);
            try {
                //服务器主动推送
                webSocket.session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 用于发送给指定客户端消息,
     *
     * @param message
     */
    public void sendMessage(String sessionId, String message) throws IOException {
        Session session = null;
        WebSocket tempWebSocket = null;
        for (WebSocket webSocket : copyOnWriteArraySet) {
            if (webSocket.session.getId().equals(sessionId)) {
                tempWebSocket = webSocket;
                session = webSocket.session;
                break;
            }
        }
        if (session != null) {
            tempWebSocket.session.getBasicRemote().sendText(message);
        } else {
            System.out.println("没有找到你指定ID的会话:{}"+sessionId);
        }
    }




}

第三步:创建页面chat.html,导入相关的js文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>websocket</title>
    <script src="stomp.min.js"></script>
    <script src="sockjs.min.js"></script>
</head>
<body>
    <h2>测试连接websocket</h2>
    <p>
        连接url:
        <input type="text" value="ws://localhost:8080/ws/myWebSocket" id="url">
        <button onclick="openWeb()">打开连接</button>
    </p>
    <p>
        发送信息内容:
        <input type="text" id="message"><button onclick="send()">发送信息</button>
    </p>
    <hr>
    <p>消息区域</p>
    <p id="show"></p>

</body>
<script type="text/javascript">
    var url="";//socket所需要的地址
    var socket;//socket对象
    function openWeb(){
        createWebSocket(document.getElementById("url").value)
    }

    //创建WebSocket连接
    function createWebSocket(url){
        if ('WebSocket' in window) {
            socket = new WebSocket(url);
        } else {
            socket = new SockJS(url);
        }

        //连接打开事件
        socket.onopen = function() {
            console.log("Socket已连接到"+url);
        };

        //收到服务器消息后响应
        socket.onmessage = function(e) {
            console.log("收到服务端消息:"+e.data)
            document.getElementById("show").innerHTML+="<br>"+e.data
        };

        //连接关闭事件
        socket.onclose = function() {
            console.log("Socket已关闭连接");
        };
        //发生了错误事件
        socket.onerror = function() {
            console.log("Socket发生了错误");
        }

        //窗口关闭时,关闭连接
        window.unload=function() {
            socket.close();
        };

    }

    function send(){
        socket.send(document.getElementById("message").value)
    }

</script>

</html>

第四步:测试。启动项目,在浏览器输入localhost:8080/chat.html,然后点击连接wensocket进行连接,接着输入要发送的信息,点击发送就可以在下面看到发送的信息。

posted @ 2021-08-25 19:36  钟小嘿  阅读(1607)  评论(0编辑  收藏  举报