在使用Netty开发Websocket服务时,通常需要解析来自客户端请求的URL、Headers等等相关内容,并做相关检查或处理。本文将讨论两种实现方法。
方法一:基于HandshakeComplete自定义事件
特点:使用简单、校验在握手成功之后、失败信息可以通过Websocket发送回客户端。
1.1 从netty源码出发
一般地,我们将netty内置的WebSocketServerProtocolHandler
作为Websocket协议的主要处理器。通过研究其代码我们了解到在本处理器被添加到Pipline
后handlerAdded
方法将会被调用。此方法经过简单的检查后将WebSocketHandshakeHandler
添加到了本处理器之前,用于处理握手相关业务。
我们都知道Websocket协议在握手时是通过HTTP(S)协议进行的,那么这个WebSocketHandshakeHandler
应该就是处理HTTP相关的数据的吧?
下方代码经过精简,放心阅读?
package io.netty.handler.codec.http.websocketx;
public class WebSocketServerProtocolHandler extends WebSocketProtocolHandler {
@Override
public void handlerAdded(ChannelHandlerContext ctx) {
ChannelPipeline cp = ctx.pipeline();
if (cp.get(WebSocketServerProtocolHandshakeHandler.class) == null) {
// Add the WebSocketHandshakeHandler before this one.
cp.addBefore(ctx.name(), WebSocketServerProtocolHandshakeHandler.class.getName(),
new WebSocketServerProtocolHandshakeHandler(serverConfig));
}
//...
}
}
我们来看看WebSocketServerProtocolHandshakeHandler
都做了什么操作。
channelRead
方法会尝试接收一个FullHttpRequest
对象,表示来自客户端的HTTP请求,随后服务器将会进行握手相关操作,此处省略了握手大部分代码,感兴趣的同学可以自行阅读。
可以注意到,在确认握手成功后,channelRead
将会调用两次fireUserEventTriggered
,此方法将会触发自定义事件。其他(在此处理器之后)的处理器会触发userEventTriggered
方法。其中一个方法传入了WebSocketServerProtocolHandler
对象,此对象保存了HTTP