,在一个handler中处理两个不同的请求,这可能是一些代码整洁的人不能容忍的。那么,是否可以对普通的HTTP请求和websocket请求使用不同的handler呢?答案是肯定的。Netty的消息处理我们知道netty中所有的消息处理都是通过handlers来实现的。为了方便,netty提供了一个简单的消息处理类SimpleChannelInboundHandler。可以通过继承重写channelRead0方法:protectedabstractvoidchannelRead0(ChannelHandlerContextctx,Imsg)throwsException;1、我们再看一下SimpleChannelInboundHandler的定义:publicabstractclassSimpleChannelInboundHandlerextendsChannelInboundHandlerAdapter1。可以看到SimpleChannelInboundHandler本身有一个泛型I,这个I就是我们要讨论的方向。如果我们想使用这个处理程序来处理所有消息,那么我可以设置为对象。如果我们只需要处理String消息,那么我们可以这样做:}}同样,如果你想同时处理HTTP和WebSocket消息,只需要将I设置为不同的类型即可。ForWebSocketFrame,wehave:publicclassServer2FrameHandlerextendsSimpleChannelInboundHandler1.ForFullHttpRequest,wehave:publicclassServer2HttpHandlerextendsSimpleChannelInboundHandler1.ForprocessingWebSocketFrame,weknowthatthereare6typesofmessagesforWebSocketFrame分别是:BinaryWebSocketFrameCloseWebSocketFrameContinuationWebSocketFramePingWebSocketFramePongWebSocketFrameTextWebSocketFrame其中真正包含内容的是TextWebSocketFrame和BinaryWebSocketFrame,这里我们对TextWebSocketFrame进行专门处理:protectedvoidchannelRead0(ChannelHandlerContextctx,WebSocketFrameframe)throwsException{if(frameinstanceofTextWebSocketFrame){//将接收到的消息转换BecomeuppercaseStringrequest=((TextWebSocketFrame)frame).text();ctx.channel().writeAndFlush(newTextWebSocketFrame(request.toUpperCase(Locale.CHINA)));}else{Stringmessage="UnsupportedFrametype:"+frame.getClass().getName();thrownewUnsupportedOperationException(message);}}HandleHTTPforHTTP对于request中的FullHttpRequest,我们只是安装普通的HTTP服务请求处理流程,这里不做赘述。编码器和解码器等等,我们是不是忘记了什么?是的,就是编码器和解码器。在上一节中,我们使用WebSocketServerHandshaker对websocket消息进行编码和解码。但是,它实际上是放在我们自定义的hadler代码中,使用起来略显不雅。java培训无所谓,netty给我们提供了一个WebSocketServerProtocolHandler类,负责websocket的编解码问题。除了处理正常的websocket握手,WebSocketServerProtocolHandler类还为我们处理了Close、Ping、Pong等常见的消息类型。而我们只需要关注真正的业务逻辑消息,非常方便。对于剩下的Text或者Binary帧数据,会交给pipeline中的下一个handler去处理。其中,Handshake有两种状态,分别是:HANDSHAKE_COMPLETE和HANDSHAKE_TIMEOUT。而HandshakeComplete包含了requestUri、requestHeaders和selectedSubprotocol的信息。最后在管道中添加WebSocketServerProtocolHandler,最后得到:publicvoidinitChannel(SocketChannelch)throwsException{ChannelPipelinepipeline=ch.pipeline();pipeline.addLast(newHttpServerCodec());pipeline.addLast(新的HttpObject3Aggregator)(655);pipeline.addLast(newWebSocketServerCompressionHandler());pipeline.addLast(newWebSocketServerProtocolHandler(WEBSOCKET_PATH,null,true));pipeline.addLast(newServer2HttpHandler());pipeline.addLast(newServer2FrameHandler());分离HTTP请求和webSocket请求的服务器就完成了。简单直观是程序员追求的世界!