我们了解下,如何从HTTP切换到WebSocket,如何检测客户端是否支持WebSocket协议

我们先考虑创建一个基于WebSocket的实时聊天应用程序来演示下

该聊天应用程序的逻辑如下:

客户端发送一个消息

该消息被广播到其他链接的客户端

图片

任何的人都可以和其他的人进行聊天,现在的客户端基本为网页端,我们专注于实现服务器端即可

图片

图片

图片 图片

如果HTTP请求指向了/ws的URI,那么HTTPRequestHandler将会调用FullHttpRequest对象上的retain()方法,并且转发给下一个InboundHandler,

如果不需要加密或者压缩,可以通过index.html进行零拷贝的使用

将index写入完成后,我们写入一个LastHttpContent标记响应的结束,如果不标注为keep-alive

还会添加一个CahnnelFutureListener到最后一次写出动作的ChannelFuture

然后调用writeAndFlush()

那么上面是简单的HTTP和webSocket协议变更的流程

对于WebSocket帧

我们说过有这着不同类型的WebSocketFrame,常见的有6种

图片

我们的聊天记录将会使用如下的几种

CloseWebSocketFrame

PingWebSocketFrame

PongWebSocketFrame

TextWebSocketFrame

首先是TextWebScoketFrame处理的Handler

代码如下

图片

然后是一个事件触发的机制

图片

上面是一个事件处理,判断是否是握手成功了,如果成功了,就将这个Piepline中移除HttpRequestHandler

上面的处理器责任是在新的客户端的WebSocket握手完成后,将通知消息写到ChannelGroup中所有的Channel来通知已经连接的客户端,并且将这个Channel加入到ChannelGroup中

对应的引导类的代码如下

图片

上面启动器类中的ChannelPipeline,其中包含的Handler如下

图片

分别由编码器 聚合器已经自定义的处理器构成

WebSocketServerProtocolHandler会在握手完成之后,将所需的ChannelHandler添加上去,移除不需要的ChannelHandler

在握手之后

我们会将HttpRequestDecoder替换为WebSocketFrameDecoder

将HttpResponseEncoder替换为WebSocketFrameEncoder

并且会根据浏览器支持的版本,选择合适的

WebSocketFrameDecoder和WebSocketFrameEncoder

然后,对应的启动类如下

图片 图片

发表评论

邮箱地址不会被公开。 必填项已用*标注