侧边栏壁纸
博主头像
实习两年半

基础不牢,地动山摇。

  • 累计撰写 44 篇文章
  • 累计创建 40 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

SpringBoot整合WebSocket两种方式

实习两年半
2023-06-17 / 0 评论 / 0 点赞 / 1,102 阅读 / 836 字
温馨提示:
本文最后更新于 2023-06-17,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

导入依赖

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

使用@ServerEndpoint注解

使用@ServerEndpoint注解的类是由WebSocket容器管理的,而不是由Spring容器管理的。因此,在@ServerEndpoint注解的类中,你不能直接注入其他Spring管理的Bean。
如果需要使用其它的bean,可以通过ApplicationContext上下文来获取指定的bean,网络上有很多这样的工具类,就不拿出来了。

  • 创建ConsoleWebSocket类
@Slf4j
@ServerEndpoint(value = "/websocket/1")
@Component
public class ConsoleWebSocket {

    /**
     * 记录当前在线连接数
     */
    private static AtomicInteger onlineCount = new AtomicInteger(0);

    /**
     * 存放所有在线的客户端
     */
    private static Map<String, Session> clients = new ConcurrentHashMap<>();


    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        onlineCount.incrementAndGet(); // 在线数加1
        clients.put(session.getId(), session);
        log.info("有新连接加入:{},当前在线人数为:{}", session.getId(), onlineCount.get());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {
        onlineCount.decrementAndGet(); // 在线数减1
        clients.remove(session.getId());
        log.info("有一连接关闭:{},当前在线人数为:{}", session.getId(), onlineCount.get());
    }

    /**
     * 收到客户端消息  后调用的方法
     *
     * @param message
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("服务端收到客户端[{}]的消息:{}", session.getId(), message);
        this.sendMessage("Hello, " + message, session);
    }

    /**
     * 服务端发送消息给客户端
     */
    public void sendMessage(String message, Session toSession) {
        try {
            log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
            toSession.getBasicRemote().sendText(message);
        } catch (Exception e) {
            log.error("服务端发送消息给客户端失败:{}", e);
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }

    /**
     * 群发消息
     *
     * @param message
     */
    public void sendMessageExcludeMe(String message, Session fromSession) {
        for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
            Session toSession = sessionEntry.getValue();
            // 排除掉自己
            if (!fromSession.getId().equals(toSession.getId())) {
                log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
                toSession.getAsyncRemote().sendText(message);
            }
        }
    }

    /**
     * 群发消息,包括自己
     *
     * @param message
     */
    public void sendMessageAll(String message) {
        for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
            Session toSession = sessionEntry.getValue();
            log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
            toSession.getAsyncRemote().sendText(message);
        }
    }
  • 定义websocket配置类

注意:

ServerEndpointExporter是Spring对WebSocket的支持类,它会自动注册被@ServerEndpoint注解标记的类作为WebSocket端点。你可以将它作为一个@Bean来配置和启用WebSocket端点。

@Configuration
public class WebSocketConfig{

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

使用 WebSocketConfigurer 配置方式

这种方式是由spring容器管理的,所以可以在WebSocketHandler放心的注入Bean

  • WebSocketConfig
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Resource
    private WebSocketHandler webSocketHandler;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(webSocketHandler, "/websocket").setAllowedOrigins("*");
    }

}

  • WebSocketHandler
@Slf4j
@Component
public class WebSocketHandler extends TextWebSocketHandler {

    @Resource
    HelloService helloService;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        // 连接建立时调用该方法
        // 可以在这里进行一些初始化操作
        log.info("链接了来了:{}", session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
        // 处理接收到的文本消息
        String payload = message.getPayload();
        // 可以在这里进行消息处理和发送消息给客户端
        log.info("接受到文本消息:{}", payload);
        sendMessageClient(session, "hello");
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        // 客户端断开连接时调用该方法
        // 可以在这里进行一些清理操作或者记录日志等
        log.info("断开链接:{}", session);
    }


    private void sendMessageClient(WebSocketSession session, String message) throws IOException {
        session.sendMessage(new TextMessage(message));
    }


}

0

评论区