WebSocket 的 6 种集成方式

科技   2024-12-13 11:24   陕西  

说到 WebSocket,估计不少开发者都有过这样的经历:在构建实时通信应用时,使用 WebSocket 的心情,简直就像是站在吃到一颗糖果的路口,盯着前方的一大堆 API 文档不知所措。😅

但是,WebSocket 真的很重要啊!它为我们提供了持久的全双工通信,特别适合实时聊天、即时通知、直播推送等应用场景。

你说,你想用 WebSocket 构建一个高效的实时系统,来个高并发、低延迟的数据传输,结果发现一堆框架和方式让你头晕转向,不知道从何下手。

这篇文章就来解开 WebSocket 集成的那点事儿,告诉你有哪些常见的集成方式,如何在 Spring Boot 中实现,甚至不止于此,还能聊聊那些不依赖 Spring 的集成方式。

1. Javax WebSocket:标准化的 WebSocket 方案

Javax WebSocket 是 Java 官方的 WebSocket 标准。它的最大优点是:简单、标准化,能支持原生的 WebSocket 客户端和服务器通信,适用于大多数纯 Java 应用。如果你是一个“纯净”主义者,想要一个不依赖 Spring 的方案,那 Javax WebSocket 完全能满足你。

服务端配置

我们可以使用 @ServerEndpoint 注解来定义 WebSocket 服务端点。并且提供了多种注解来处理连接、消息、错误等回调事件。

例如,定义一个简单的 WebSocket 服务端:

@Component
@ServerEndpoint("/websocket/{type}")
public class JavaxWebSocketServerEndpoint {

    @OnOpen
    public void onOpen(Session session, EndpointConfig config, @PathParam("type") String type) {
        // 连接建立时的回调
        System.out.println("连接建立:类型 = " + type);
    }

    @OnClose
    public void onClose(Session session, CloseReason reason) {
        // 连接关闭时的回调
        System.out.println("连接关闭:" + reason.getReasonPhrase());
    }

    @OnMessage
    public void onMessage(Session session, String message) {
        // 接收消息的回调
        System.out.println("收到消息: " + message);
    }

    @OnError
    public void onError(Session session, Throwable e) {
        // 错误处理
        System.out.println("发生错误: " + e.getMessage());
    }
}

为了启用 Javax WebSocket 端点,我们还需要配置 ServerEndpointExporter

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

客户端配置

客户端也可以使用类似的方式来处理 WebSocket 连接。我们使用 @ClientEndpoint 注解来定义客户端行为。

@ClientEndpoint
public class JavaxWebSocketClientEndpoint {

    @OnOpen
    public void onOpen(Session session) {
        // 连接建立时的回调
        System.out.println("连接已建立!");
    }

    @OnClose
    public void onClose(Session session, CloseReason reason) {
        // 连接关闭时的回调
        System.out.println("连接关闭:" + reason.getReasonPhrase());
    }

    @OnMessage
    public void onMessage(Session session, String message) {
        // 接收到消息时的回调
        System.out.println("接收到消息: " + message);
    }

    @OnError
    public void onError(Session session, Throwable e) {
        // 错误处理
        System.out.println("发生错误: " + e.getMessage());
    }
}

客户端的连接过程则是通过 WebSocketContainer 完成的:

WebSocketContainer container = ContainerProvider.getWebSocketContainer();
Session session = container.connectToServer(JavaxWebSocketClientEndpoint.classuri);

2. Spring WebMVC:经典的 WebSocket 集成

如果你已经在 Spring Boot 中使用了 WebMVC(大多数人都是),那么你可以利用 Spring 提供的 WebSocket 集成支持,使用 WebSocketHandler 来处理消息。

服务端配置

你需要实现一个 WebSocketHandler,并注册到 Spring 的 WebSocket 配置中:

public class ServletWebSocketServerHandler implements WebSocketHandler {
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 连接建立
        System.out.println("连接已建立");
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        // 接收消息
        System.out.println("接收到消息: " + message.getPayload());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        // 连接关闭
        System.out.println("连接关闭");
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
}

然后在 Spring 配置中,使用 @EnableWebSocket 启用 WebSocket 支持:

@Configuration
@EnableWebSocket
public class ServletWebSocketServerConfigurer implements WebSocketConfigurer {

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

客户端配置

在客户端,Spring 也提供了 WebSocketHandler 方式来进行通信,示例如下:

public class ServletWebSocketClientHandler implements WebSocketHandler {
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 连接建立
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        // 接收消息
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        // 连接关闭
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
}

3. Spring WebFlux:适应高并发的 WebSocket 集成

如果你对反应式编程情有独钟,或者你的应用需要处理高并发、异步的请求,Spring WebFlux 会是一个不错的选择。

服务端配置

WebFlux 中的 WebSocket 集成与传统 WebMVC 很相似,不过,它使用的是反应式的 MonoFlux 来处理消息的发送和接收。

public class ReactiveWebSocketServerHandler implements WebSocketHandler {

    @NonNull
    @Override
    public Mono<Void> handle(WebSocketSession session) {
        Mono<Void> send = session.send(Flux.create(sink -> {
            // 发送消息
        }));

        Mono<Void> receive = session.receive()
                .doOnNext(message -> {
                    // 处理接收到的消息
                })
                .doOnError(Throwable::printStackTrace)
                .then();

        return Mono.zip(send, receive).then();
    }
}

然后,你需要通过 HandlerMapping 来注册 WebSocket 处理器:

@Component
public class ReactiveWebSocketServerHandlerMapping extends SimpleUrlHandlerMapping {
    public ReactiveWebSocketServerHandlerMapping() {
        Map<String, WebSocketHandler> map = new HashMap<>();
        map.put("/websocket/**"new ReactiveWebSocketServerHandler());
        setUrlMap(map);
        setOrder(100);
    }
}

客户端配置

WebFlux 的客户端配置也是基于 WebSocketHandlerWebSocketSession

public class ReactiveWebSocketClientHandler implements WebSocketHandler {

    @NonNull
    @Override
    public Mono<Void> handle(WebSocketSession session) {
        Mono<Void> send = session.send(Flux.create(sink -> {
            // 发送消息
        }));

        Mono<Void> receive = session.receive()
                .doOnNext(message -> {
                    // 处理接收到的消息
                })
                .doOnError(Throwable::printStackTrace)
                .then();

        return Mono.zip(send, receive).then();
    }
}
WebSocketClient client = new ReactorNettyWebSocketClient();
WebSocketHandler handler = new ReactiveWebSocketClientHandler();
client.execute(uri, handler).subscribe();

4. 总结:选择合适的 WebSocket 集成方式

不同的 WebSocket 集成方式适合不同的场景:

  • Javax WebSocket:适合纯 Java 应用,不依赖于 Spring,简单直接。
  • Spring WebMVC:适合传统基于 Servlet 的 Web 应用,容易上手,适合大多数 Spring Boot 项目。
  • Spring WebFlux:适合高并发、异步场景,特别适合反应式编程需求。

无论是哪种方式,WebSocket 都是实现实时通信的利器。在选择时,根据项目的需求、并发量、技术栈来决定使用哪种集成方式。总之,WebSocket 的优势,别说我没告诉你,真的是太爽了!😎

对编程、职场感兴趣的同学,可以链接我,微信:coder301 拉你进入“程序员交流群”。
🔥东哥私藏精品 热门推荐🔥

东哥作为一名超级老码农,整理了全网最全《Java高级架构师资料合集》

资料包含了《IDEA视频教程》《最全Java面试题库》、最全项目实战源码及视频》及《毕业设计系统源码》总量高达 650GB 。全部免费领取!全面满足各个阶段程序员的学习需求。

Java面试那些事儿
回复 java ,领取Java面试题。分享AI编程,Java教程,Java面试辅导,Java编程视频,Java下载,Java技术栈,AI工具,Java开源项目,Java简历模板,Java招聘,Java实战,Java面试经验,IDEA教程。
 最新文章