具体需求:
在建立websocket连接后,对用户传过来的url中的token参数进行验证,再从缓存中获取该用户信息
方法步骤:
1.继承netty包里的WebSocketServerProtocolHandler,重写里面的handlerAdded方法,用自己handshakehandler来替换它
@Override
public void handlerAdded(ChannelHandlerContext ctx) {
ChannelPipeline cp = ctx.pipeline();
if (cp.get(ZZKWebSocketServerProtocolHandshakeHandler.class) == null) {
// Add the WebSocketHandshakeHandler before this one.
**********在这里写入自己的HandshakeHandler*********
ctx.pipeline().addBefore(ctx.name(), ZZKWebSocketServerProtocolHandshakeHandler.class.getName(),
new ZZKWebSocketServerProtocolHandshakeHandler(websocketPath, subprotocols,
allowExtensions, maxFramePayloadSize, allowMaskMismatch, checkStartsWith));
}
****************************************************
if (cp.get(Utf8FrameValidator.class) == null) {
// Add the UFT8 checking before this one.
ctx.pipeline().addBefore(ctx.name(), Utf8FrameValidator.class.getName(),
new Utf8FrameValidator());
}
}
2.复制WebSocketServerProtocolHandshakeHandler这个类,重新命名,在里面的channelRead方法里写入自己的业务逻辑,具体位置在添加channelfuture的闭包里,if(future.isSuccess())..............
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
final FullHttpRequest req = (FullHttpRequest) msg;
if (isNotWebSocketPath(req)) {
ctx.fireChannelRead(msg);
return;
}
try {
if (req.method() != GET) {
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN));
return;
}
final WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
getWebSocketLocation(ctx.pipeline(), req, websocketPath), subprotocols,
allowExtensions, maxFramePayloadSize, allowMaskMismatch);
final WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req);
if (handshaker == null) {
WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
} else {
final ChannelFuture handshakeFuture = handshaker.handshake(ctx.channel(), req);
handshakeFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) {
ctx.fireExceptionCaught(future.cause());
} else {
// Kept for compatibility
ctx.fireUserEventTriggered(
WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE);
ctx.fireUserEventTriggered(
new ZZKWebSocketServerProtocolHandler.HandshakeComplete(
req.uri(), req.headers(), handshaker.selectedSubprotocol()));
//这里写业务逻辑处理
BeanHolder.get(MessageHelperService.class).validate(ctx, req);
}
}
});
ZZKWebSocketServerProtocolHandshakeHandler.setHandshaker(ctx.channel(), handshaker);
ctx.pipeline().replace(this, "WS403Responder",
ZZKWebSocketServerProtocolHandler.forbiddenHttpRequestResponder());
}
} finally {
req.release();
}
}
最后在netty的handler链中加入该handler
ChannelPipeline pipeline = channel.pipeline();
....
pipeline.addLast(new ZZKHttpRequestHandler());//区分http请求,读取html页面并写回客户端浏览器
pipeline.addLast(new ZZKWebSocketServerProtocolHandler());//会拦截该地址的请求,会区分访问是控制针访问还是数据帧访问,数据帧访问会交给自己的控制器处理
pipeline.addLast(new ZZKChatServerHandler());//向客户端发送数据
网友评论