在SpringBoot中使用WebSocket的步骤

411 阅读1分钟

一、导入 WebSocket 的坐标

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

二、将 WebSocket 端点类的实例注册到 Spring 容器

@Configuration
public class WebSocketConfig {

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

在上面的代码中,创建并注册了 ServerEndpointExporter bean。这将启用自动发现并注册使用 @ServerEndpoint 注解的 WebSocket 端点类。

三、一个简单的 WebSocket 端点类示例如下

@ServerEndpoint("/websocket")
public class MyWebSocketEndpoint {

    @OnOpen
    public void onOpen(Session session) {
        // WebSocket 连接已打开
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        // 收到来自客户端的消息
    }

    @OnClose
    public void onClose(Session session, CloseReason reason) {
        // WebSocket 连接已关闭
    }
}

四、详细的 WebSocket 端点类示例如下

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

@Slf4j
@Component
@ServerEndpoint("/ws/{id}")
public class MyWebSocketEndpoint {
    private Session session; //与某个客户端的连接会话,需要通过它来给客户端发送数据

    // 保存所有的客户端连接
    private static final CopyOnWriteArraySet<WebSocketServer> webSockets = new CopyOnWriteArraySet<>();
    // 绑定客户端会话和该用户 一对一的 关系,实现向指定的客户端连接推送消息
    private static final ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();

    /**
     * 打开连接
     *
     * @param session session
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("id") String id) {
        this.session = session;
        webSockets.add(this);

        sessions.put(id, session);

        log.info("websocket消息: 有新的连接{},总数为:{}", id, webSockets.size());
    }

    /**
     * 接受客户端消息
     *
     * @param message message
     */
    @OnMessage
    public void onMessage(String message) {
        log.info("收到客户端消息:{}", message);
    }

    /**
     * 关闭连接
     */
    @OnClose
    public void close() {
        webSockets.remove(this);
        log.info("websocket消息: 有连接断开,总数为:" + webSockets.size());
    }

    /**
     * 向所有客户端连接发送消息
     *
     * @param message 消息
     */
    public void sendMessageToAllClient(String message) {
        webSockets.forEach((websocket) -> {
            if (websocket.session != null && websocket.session.isOpen()) {
                websocket.session.getAsyncRemote().sendText(message);
            }
        });
    }

    /**
     * 向指定的连接发送消息
     *
     * @param key     key
     * @param message msg
     */
    public void sendMessageToOne(String key, String message) {
        Session session = sessions.get(key);
        if (session != null && session.isOpen()) {
            try {
                session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("当前连接已断开或连接不存在!");
        }
    }

}