73 记一次 sprintboot 项目改造之后处理不了 websocket 消息

Posted 蓝风9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了73 记一次 sprintboot 项目改造之后处理不了 websocket 消息相关的知识,希望对你有一定的参考价值。

前言

呵呵 最近有一次 websocket 项目的改造, 呵呵 这个改造出现了一些事情 

然后 之后改造完成之后, 启动项目 来进行测试, 擦 websocket 怎么创建连接 gg 了?? 

然后 就有了后面的额一系列的调试, 当然 最后也是 找到了问题的原因  

问题的效果

正常的创建 websocket 的连接 

异常的创建 websocket 的连接 

正常场景的调试

我们先看一下 正常的情况, 在 Http11Processor.service 上面打上断点, 先大致的看一下执行的流程, 最后返回的是 UPGRADING 状态 

我们再看一下 这里的 isUpgrade 的判断标准, 是 upgradeToken 不为 null, 那么是哪里设置的 upgradeToken 呢, 这里怕是就是我们问题的突破口了 

我们看一下设置 upgradeToken 的地方, 纵观一下堆栈信息, 这里似乎起作用的是 WsFilter, 这里面判断的 doUpgrade, 然后通知到 Request, Processor, 流程大致是 WsFilter -> Request -> Processor 

我们大致看一下 WsFilter 中的一些处理 

sc 看这里的样子应该就是 websocket 服务的管理者, 如果没有 endpoint 注册, 或者不是 websocket 请求, 直接放过 

然后查找当前 websocket 是否匹配某一个 endpoint, 如果灭有找到, 直接放过 

否则 doUpgrade 

异常场景的调试

接下来我们看看 存在问题的场景 

可以看到我们这里的情况是 灭有 endpoint 注册?, 那么我不是创建了 WebsocketServer 监听 /websocket/* 么, 怎么会检测不到呢?, 呵呵 继续看一下这里面的 areEndpointsRegistered 

这里面的判断是一个 endpointsRegistered 的标记, 更新标记是在 WebServerContainer. addEndpoint 

呵呵 原来是 Spring 容器中需要一个 ServerEndpointExporter 来处理一些 endpoint 的注册的相关工作, 注册到 WebServerContainer 里面 

这时候 我看了一下代码的更新记录, 发现原来的 XXAutoConfiguration 里面有一个 ServerEndpointExporter 的实例 

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

呵呵 加上这个实例, 再来试试 

呵呵 问题处理了 

一些扩展 

1. WsFilter 中怎么判断是否是 websocket 请求 的呢? 

是 http 请求, 并且需要包含 Upgrade 的请求头, 值为 websocket, 并且是 get 请求 

2. 怎么根据 url 匹配哪一个服务来处理呢?

精确匹配 和 模式匹配, 显然我们这里走的是 模式匹配 

具体的匹配规则, 可以参见代码, 有一个标记判断模式中的是 literal 还是参数, 如果是 literal 需要 请求path 中的对应的 segment 匹配, 如果是参数, 存放到参数 slot 里面 

以上是关于73 记一次 sprintboot 项目改造之后处理不了 websocket 消息的主要内容,如果未能解决你的问题,请参考以下文章

项目实践记一次对后端服务进行跨域改造和HTTPS升级的探究和实践

项目实践记一次对后端服务进行跨域改造和HTTPS升级的探究和实践

项目实践记一次对后端服务进行跨域改造和HTTPS升级的探究和实践

记一次改造react脚手架的过程

记一次企业级爬虫系统升级改造:文本分析与数据建模规则化处理

记一次改造react脚手架的过程