WebSocket支持

SpringWebFlux对WebSocket有良好的支持,基于SpringWebFlux的异步非阻塞特性我们能很容易的开发高并发WebSocket服务,而且它的API设计与SpringMVC保持了一致,使用起来也相对简单。这篇笔记我们对SpringWebFlux中WebSocket的使用进行介绍。

使用WebSocket

和SpringMVC一样,SpringWebFlux中使用WebSocket需要创建一个实现WebSocketHandler的类,只不过这里的WebSocketHandler来自org.springframework.web.reactive.socket包下。

package com.gacfox.demo.ws;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.reactive.socket.WebSocketHandler;
import org.springframework.web.reactive.socket.WebSocketMessage;
import org.springframework.web.reactive.socket.WebSocketSession;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

@Slf4j
public class DemoWebSocketHandler implements WebSocketHandler {
    @Override
    public Mono<Void> handle(WebSocketSession session) {
        Flux<WebSocketMessage> outputFlux = session.receive()
                .map(message -> {
                    String payload = message.getPayloadAsText(StandardCharsets.UTF_8);
                    log.info("payload: {}", payload);
                    return payload;
                })
                .map(messageText -> {
                    String payload = "echo: " + messageText;
                    return session.textMessage(payload);
                });
        return session.send(outputFlux);
    }
}

代码中,我们的handle()方法接收WebSocketSession类型的参数,它是SpringWebFlux中处理WebSocket的会话对象,这个对象用于在服务器和客户端之间管理WebSocket连接,它提供了发送和接收消息的方法,并包含了会话上下文相关的信息。方法内部,我们首先调用了WebSocketSessionreceive()方法,它返回Flux<WebSocketMessage>类型的Publisher,我们在这里开始以响应式流的方式定义消息的处理管线,我们先取出收到的消息字符串并打印了消息内容,生成了响应信息字符串,然后将其封装回WebSocketMessage作为响应。最后,我们调用了send()方法向客户端发送消息。

定义好DemoWebSocketHandler后我们还需要将其注册到SpringWebFlux框架,这需要构建并注册一个HandlerMapping对象,下面是一个例子。

package com.gacfox.demo.config;

import com.gacfox.demo.ws.DemoWebSocketHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.HandlerMapping;
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
import org.springframework.web.reactive.socket.WebSocketHandler;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class WebConfig {
    @Bean
    public HandlerMapping handlerMapping() {
        Map<String, WebSocketHandler> map = new HashMap<>();
        map.put("/ws", new DemoWebSocketHandler());
        int order = -1;
        return new SimpleUrlHandlerMapping(map, order);
    }
}

代码中,我们指定DemoWebSocketHandler处理的URL是/ws,它的order被设置为-1,表示这个HandlerMapping的优先级最高,确保/ws路径能被我们的DemoWebSocketHandler最优先处理。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap