Solon v3.0.3

二、WebSocket 开发进阶 (v2)

</> markdown

此内容 v2.6.0 后支持


1、增强接口说明

  • 增强监听器
接口说明补充
SimpleWebSocketListener简单监听器不需要实现所有方法
PipelineWebSocketListener管道监听器可让多个监听器排成一个管道依次执行
PathWebSocketListener路径监听器
ContextPathWebSocketListener上下文路径支持监听器(如果有配置,会自动添加)
ToSocketdWebSocketListener协议转换监听器将 WebSocket 协议,转换为 Socket.D 应用协议
  • 组件路由器
接口说明
WebSocketRouter接收 @ServerEndpoint 组件的注册并提供路由。且,对接适配层

2、关于 WebSocketRouter

WebSocketRouter 是 WebSocket 服务的总路由器,由 PipelineWebSocketListener + PathWebSocketListener + ContextPathWebSocketListener(如果有 server.contextPath 配置,会自动添加) 组合而成。它主要提供三个功能:

  • 接收 @ServerEndpoint 组件的注册并提供路由
  • 提供前置与后置监听拦截支持
  • 适配第三方框架时,通过它完成适配对接

a) 如何获得 WebSocketRouter

//字段注入的方式
@Inject
WebSocketRouter webSocketRouter;

//参数注入的方式
@Bean
public void websocketInit(@Inject WebSocketRouter webSocketRouter){
}

//手动获取方式
WebSocketRouter.getInstance();

b) 认识 WebSocketRouter 的接口

public class WebSocketRouter {
    //用于手动获取单例
    public static WebSocketRouter getInstance();

    //添加前置监听
    public void before(WebSocketListener listener);
   //添加前置监听,如果没有同类型的
    public void beforeIfAbsent(WebSocketListener listener);
    //添加路由(主监听)
    public void of(String path, WebSocketListener listener);
    //添加后置监听
    public void after(WebSocketListener listener);
    //添加后置监听,如果没有同类型的
    public void afterIfAbsent(WebSocketListener listener) ;
}

c) 使用 WebSocketRouter

  • 添加前置拦截监听
@Configuration
public class WebSocketRouterConfig0 {
    @Bean
    public void init(@Inject WebSocketRouter webSocketRouter){
        //添加前置监听(拦截监听)
        webSocketRouter.before(new SimpleWebSocketListener(){
            @Override
            public void onMessage(WebSocket socket, String text) throws IOException {
                //...
            }
        });
    }
}
  • 更换 ContextPathWebSocketListener

如果不喜欢框架提供的 ContextPathWebSocketListener 策略?可以手动添加(优先使用用户添加的)

@Configuration
public class WebSocketRouterConfig0 {
    @Bean
    public void init(@Inject WebSocketRouter webSocketRouter){
        webSocketRouter.before(new ContextPathWebSocketListener(true)); 
    }
}

3、使用增强监听器组合复杂效果

给某频道定制专属策略。使用管道监听器组织多层监听,使用路由监听器为二级频道定策略。

@ServerEndpoint("/demo2/**")
public class WebSocketDemo2 extends PipelineWebSocketListener {
    public WebSocketDemo2() {
        next(new SimpleWebSocketListener() {
            @Override
            public void onMessage(WebSocket socket, String text) throws IOException {
                //加个拦截
                super.onMessage(socket, text);
            }
        }).next(new PathWebSocketListener()
                .of("/demo2/user/{id}", new SimpleWebSocketListener() {
                    @Override
                    public void onMessage(WebSocket socket, String text) throws IOException {
                        //普通频道
                        super.onMessage(socket, text);
                    }
                }).of("/demo2/admin", new SimpleWebSocketListener() {
                    @Override
                    public void onOpen(WebSocket socket) {
                        //管理员频道,加个鉴权
                        if ("admin".equals(socket.param("u")) == false) {
                            socket.close();
                        }
                    }
                })
        );
    }
}