SpringBoot WebSocket实现前后端交互 (转)

原文:https://www.cnblogs.com/xiaozhengtongxue/p/13448778.html

  • websocket: 在浏览器和服务器之间建立TCP连接,实现全双工通信
    springboot使用websocket有两种方式,一种是实现简单的websocket,另外一种是实现STOMP协议。本篇讲述如何使用springboot实现简单的websocket。

直接在pom.xml中导入依赖。

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

首先注入一个ServerEndpointExporterBean,该Bean会自动注册使用@ServerEndpoint注解申请的websocket endpoint,代码如下:

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

新建websocket  服务端,在其中处理websocket 逻辑

@Component  //注册到容器中
@ServerEndpoint("/webSocket")  //接收websocket请求路径
@Slf4j
public class WebSocket {
    //当前连接(每个websocket连入都会创建一个WebSocket实例)
    private Session session;

    //定义一个websocket容器存储session,即存放所有在线的socket连接
    private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>();

    //处理连接建立
    @OnOpen
    public void opOpen(Session session){
        this.session = session;
        log.info("【有新的客户端连接了】:{}",session.getId());
        webSocketSet.add(this);  //将新用户加入在线组
        log.info("【websocket消息】有新的连接,总数:{}",webSocketSet.size());
    }

    //处理连接关闭
    @OnClose
    public void Onclose(){
        webSocketSet.remove(this);
        log.info("【websocket消息】连接断开,总数:{}",webSocketSet.size());
    }

    //接受消息
    @OnMessage
    public void onMessage(String message){
        log.info("【websocket消息】收到客户端发来的消息:{}",message);
    }

    // 群发消息
    public void sendMessage(String message) {
        for (WebSocket webSocket : webSocketSet) {
            log.info("【websocket消息】广播群发消息,message={}",message);
            try {
                webSocket.session.getBasicRemote().sendText(message);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

客户可以使用freeMarker模板工具实现。

前端实现,建议:https://blog.csdn.net/LiLi_code/article/details/86583347

由于部分浏览器可能不支持,可以先测试,代码如下:

<script>
    var websocket = null;
    if('WebSocket' in window){
        websocket = new WebSocket('ws://localhost:8080/webSocket');
    }else{
        alert('当前浏览器不支持websocket消息通知');
    }

    //连接成功建立的回调方法
    websocket.onopen = function (event) {
        console.log("ws建立连接成功");
    }

    //连接关闭的回调方法
    websocket.onclose = function (event) {
        console.log("ws连接关闭");
    }

    //接收到消息的回调方法
    websocket.onmessage = function (event) {
        /*setMessageInnerHTML(event.data);*/
       // alert("ws接收返回消息:"+event.data);
        console.log("服务器返回消息: " + event.data);
        //弹窗提醒(要用到JQuary,所以要先引入JQuary)   播放音乐
        $('#mymodal').modal('show')
    }

    //连接发生错误的回调方法
    websocket.onerror = function(event){
        alert('websocket通信发生错误!')
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function() {
        websocket.close();
    }
    </script>

测试:(项目实现客户创建订单之后,前台发出提醒)

@Autowired
private WebSocket webSocket;

@Override
    @Transactional
    public OrderDTO create(OrderDTO orderDTO) {//创建订单
        。。。。(具体代码省略)

       //创建新订单  发送websocket消息
        webSocket.sendMessage(orderDTO.getOrderId());
        return orderDTO;
    }

添加新订单:


接收到websocket消息



前端实现,建议:https://blog.csdn.net/LiLi_code/article/details/86583347

index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>聊天室</title>
    </head>
    <body>
    <div id="main">
        <p>
            <input type="text" id="username" placeholder="请输入用户名"/>
            <button type="button" id="addBtn">加入</button>
        </p>
        <p>
            <input type="text" id="message" placeholder="请输入聊天信息"/>
            <button type="button" id="sendBtn" disabled>发送</button>
        </p>
        <ul id="msg"></ul>
    </div>
     
    </body>
    <script>
        window.onload = function () {
            //获取button对象
            let addBtn = document.getElementById("addBtn")
            let sendBtn = document.getElementById("sendBtn")
            let username = document.getElementById("username")
            var message = document.getElementById("message")
            //定义全局
            let ws = null;
            addBtn.onclick = function () {
                join()
     
            }
     
            //给文本框添加键盘点击事件
            username.onkeyup = function (e) {
                //如果输入的是回车,进聊天室
                if (e.keyCode === 13) {
                    join()
                    username.disabled = true
                }
            }
     
     
            sendBtn.onclick = function () {
                sendMessage()
            }
            message.onkeyup = function(e){
                if(e.keyCode === 13) sendMessage()
            }
     
            function join() {
                addBtn.disabled = true
                sendBtn.disabled = false
                // 创建WebSocket对象,WebSocket使用的是ws协议
                ws = new WebSocket('ws://localhost:2555')
                ws.onopen = function () {
                    let username = document.getElementById("username").value
                    // 项服务器端发送消息
                    ws.send(
                            // 往后台发送json字符串
                            JSON.stringify({
                                username: username,
                                type: 'login'  //添加的对象
                            })
                    )
                }
                // onmessage与ws已经绑定,接受消息回来的时候还是会回到这里来
                // 服务器发送消息后会触发
                ws.onmessage = function (e) {
                    console.log(e.data)
                    //字符串对象转json对象
                    let data = JSON.parse(e.data)
                    let show
                    switch (data.type) {
                        case 'login': //新用户
                            show = `${data.username}加入了房间`
                            break;
                        case 'msg': // 有新的聊天信息
                            show = `${data.username} ${data.time} <br> ${data.message}`
                            break
                        case 'leave': //有人离开聊天室
                            show = `${data.username}离开了房间 ${data.time}`
                            break;
                    }
                    let li = document.createElement("li")
                    li.innerHTML = show
                    document.getElementById("msg").append(li)
                }
            }
     
            function sendMessage() {
                let username = document.getElementById("username").value
                let msg = document.getElementById("message").value
                //发送聊天消息给服务器
                ws.send(JSON.stringify({
                    username: username,
                    message: msg,
                    type: 'msg'
                }))
                document.getElementById("message").value = ''
            }
        }
    </script>
    </html>
app.js

    //后台服务器代码
    //引入websocket模块
    let ws = require('nodejs-websocket')
     
    //创建服务对象启动,监听端口号是2555
    let server = ws.createServer((conn)=>{
        console.log('有人连接...')
        //当客户端发消息时会触发text事件
        conn.on('text',(str)=>{
            let data = JSON.parse(str)
            console.log(data)
            //判断接受消息的类型
            switch(data.type){
                case 'login': //新用户加入
                    conn.nickname = data.username //保存用户名属性
                    broadcast(
                        //发送json字符串告诉客户端有新用户加入
                        JSON.stringify({
                            username:data.username,
                            time:getTime(),
                            type:data.type
                        })
                    )
                    break
                case 'msg':
                    broadcast(
                        JSON.stringify({
                            username:data.username,
                            time:getTime(),
                            message:data.message,
                            type:data.type
                        })
                    )
                    break
            }
        })
     
        //监听错误信息
        conn.on('error',(err)=>{
            console.log(err)
        })
     
        //监听断开连接
        conn.on('close',()=>{
            broadcast(
                JSON.stringify({
                    username:conn.nickname,
                    time:getTime(),
                    type:'leave'
                })
            )
        })
     
    }).listen(2555)
     
    //给所有客户端连接发送消息
    function broadcast(str){
        //遍历所有的客户端连接
        server.connections.forEach((conn)=>{
            //发送消息
            conn.send(str)
        })
    }
     
    function getTime(){
        var date = new Date();
        var hour = date.getHours();
        var min = date.getMinutes()
        var sec = date.getSeconds()
        return hour + ":" + min + ":" + sec
    }

不要忘记实现导入websocket框架;

  1. 安装包 nodejs-websocket
  2. npm install nodejs-websocket
原文地址:https://www.cnblogs.com/lshan/p/14047527.html