Websocket在Java中的实践——自动注册端点

发布于:2024-06-27 ⋅ 阅读:(147) ⋅ 点赞:(0)

《Websocket在Java中的实践——握手拦截器》中我们使用握手拦截器实现了路径解析的工作。这个过程略显复杂,因为路径解析这样比较底层的工作应该由框架来解决,而不应该交由开发者来做。本文介绍的自动注册端点的功能就可以很优雅的解决这个问题。

依赖

在pom.xml中新增

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

自动注册端点

当Spring容器启动时,serverEndpointExporter会扫描所有带有@ServerEndpoint注解的类,并将这些类注册为WebSocket端点,这样客户端就可以通过相应的URL与这些端点建立WebSocket连接。

package com.nyctlc.endpointexporter.config;

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

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

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

}

端点

@ServerEndpoint是一个注解,用于声明一个类为WebSocket服务器端点。在Java中,特别是在使用Jakarta WebSocket API(之前称为Java API for WebSocket)时,这个注解非常关键。通过使用@ServerEndpoint注解,可以将一个普通的类转变为WebSocket服务器端点,从而能够处理WebSocket连接、消息和其他事件。

package com.nyctlc.endpointexporter.handler;

import java.util.concurrent.ConcurrentHashMap;

import org.springframework.stereotype.Component;

import jakarta.websocket.OnClose;
import jakarta.websocket.OnError;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;

@Component
@ServerEndpoint("/websocket/{userId}")
public class WebSocketHandler {

    private static final ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

    // WebSocket handler implementation
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") String userId){
        sessionPools.put(userId, session);
        // WebSocket onOpen implementation
    }

    @OnClose
    public void onClose(Session session, @PathParam(value = "userId") String userId){
        // WebSocket onClose implementation
    }

    // Other WebSocket methods
    @OnMessage
    public void onMessage(Session session, String message, @PathParam(value = "userId") String userId){
        // WebSocket onMessage implementation
        for (Session s : sessionPools.values()) {
            if (s.equals(session)) {
                continue;
            }
            s.getAsyncRemote().sendText(userId+" said: " + message);
        }
    }

    @OnError
    public void onError(Session session, Throwable throwable, @PathParam(value = "userId") String userId){
        // WebSocket onError implementation
    }
}

测试

在这里插入图片描述
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到