Loading

使用WebSocket进行前后端通信

1、需要在pom文件中引入对websocket的依赖

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

2、application.properties

# 应用服务 WEB 访问端口
server.port=8080

3、客户端代码(index.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>websocketTest</title>
</head>
<body>
    <span style="color: green" id="online">在线</span>
    <span style="color: red" id="unline">离线</span>
    请输入要发生给后台的信息:<input type="text" id="message"><button onclick="sendMess()">发送</button>
    <button onclick="closeWebScoket()">关闭websocket连接</button>
    <div id="backMess"></div>
</body>
<script>
    var socket = new WebSocket("ws://localhost:8080/chat");

    socket.onopen = function () {
        var unline = document.getElementById("unline");
        unline.style.display = "none";
        var online = document.getElementById("online");
        online.style.display = "block";
    }

    socket.onmessage = function (event) {
        console.log(event)
        document.getElementById("backMess").innerText = event.data;
    }

    socket.onclose = function () {
        var unline = document.getElementById("unline");
        unline.style.display = "block";
        var online = document.getElementById("online");
        online.style.display = "none";
    }

    socket.onerror = function () {

    }
    
    function closeWebScoket() {
        socket.close();
    }

    function sendMess() {
        var message = document.getElementById("message");
        socket.send(message.value);
    }

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

4、服务端代码

package com.bitzh.demo.server;

import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

@ServerEndpoint(value = "/chat")
@Component
public class WebSocketServer {

    private static int onlineCount = 0;
    private static final Set<WebSocketServer> connections = new CopyOnWriteArraySet<>();
    private Session session;

    @OnOpen
    public void OnOpen(Session session) {
        this.session = session;
        connections.add(this);
        String message = String.format("%s %s", session.getId(), "has joined.");
        broadcast(message);
    }

    @OnClose
    public void OnClose() {
        connections.remove(this);
        String message = String.format("%s %s", session.getId(), "has disconnected.");
        broadcast(message);
    }

    @OnMessage
    public void OnMessage(String message) {
        String msg = String.format("%s %s %s", session.getId(), "say", message);;
        broadcast(msg);
    }

    @OnError
    public void onError(Throwable t) throws Throwable {
        t.printStackTrace();
    }

    private static void broadcast(String msg) {
        for (WebSocketServer client : connections) {
            try {
                synchronized (client) {
                    //将消息广播给其他会话
                    client.session.getBasicRemote().sendText(msg);
                }
            } catch (IOException e) {
                connections.remove(client);
                try {
                    client.session.close();
                } catch (IOException e1) {}
                String message = String.format("%s %s",client.session.getId(), "has been disconnected.");
                broadcast(message);
            }
        }
    }
}

5、注意:需要开启对WebSocket支持,需要写一个配置类,代码如下:

package com.bitzh.demo.config;

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

/**
 * 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint
 */
@Configuration
public class WebSocketConfig {

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

}

5、完全上述步骤后,启动后台服务器

6、访问http://localhost:8080/index.html

7、页面中可以看到这些信息

8、在输入框输入要向服务端发送的消息,点击发送,可以看到服务端也成功得将消息返回给了客户端

9、点击关闭websocket连接按钮,触发了客户端的onclose方法,此时状态变为离线

posted @ 2022-01-15 20:44  爱睡懒觉的我  阅读(510)  评论(0)    收藏  举报