Nettyとwebsocketはどのようにパラメータの伝達を実現します

4169 ワード

Websocket:
WebsocketはHTML 5に新たに追加されたプロトコルで、サーバとブラウザの間に制限されない双方向チャネルを確立し、サーバがブラウザにメッセージをアクティブにプッシュすることを実現します.
WebsocketはHttpプロトコルを用いて実現される.Webscoket接続はすべてブラウザで開始されます.彼の接続リクエストはhttpリクエストです.
要求フォーマットは次のとおりです.
GET ws://localhost:3000/ws/chat HTTP/1.1
Host: localhost
Upgrade: websocket                           //           websocket  
Connection: Upgrade
Origin: http://localhost:3000
Sec-WebSocket-Key: client-random-string      //      
Sec-WebSocket-Version: 13

サーバの応答:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: server-random-string

応答コード101は、プロトコルが変換されることを表す.では、パラメータを渡します.つまり、今回のhttpで接続を確立します.
接続を確立するときにリクエストを切り取り、パラメータを外して、新しいパッケージurlから取り出します.
pipelineに次のhandlerを追加します.
                ch.pipeline().addLast("http-decoder", new HttpServerCodec());
		//   ObjectAggregator   ,                FullHttpRequest  FullHttpResponse
		ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65536));
		//   chunked               (     ),         ,  java    
		ch.pipeline().addLast(new ChunkedWriteHandler());
		//      handler
		ch.pipeline().addLast( handler);
		//   webSocket hanlder
		ch.pipeline().addLast(new WebSocketServerProtocolHandler("/ws"));

順序は間違ってはいけません.自分で実践して、コード玄学(実は自分で学んだのが不十分です)
そして自分のhandlerでreadメソッドを書き換える(readはread 0ではないことに注意)
@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		if (null != msg && msg instanceof FullHttpRequest) {
			logger.info("    token");
                        //   http  
			FullHttpRequest request = (FullHttpRequest) msg;
                        //      			
                        String uri = request.uri();
			//     websocket  ,            (   token)
                        String origin = request.headers().get("Origin");
			if (null == origin) {
				ctx.close();
			} else {
				if (null != uri && uri.contains("/ws") && uri.contains("?")) {
					String[] uriArray = uri.split("\\?");
					if (null != uriArray && uriArray.length > 1) {
						String[] paramsArray = uriArray[1].split("=");
						if (null != paramsArray && paramsArray.length > 1) {
							srctoken = paramsArray[1];
							logger.info("  token  ");
						}
					}
                                        //        
					request.setUri("/ws");
				}
			}
		}
                //      
		super.channelRead(ctx, msg);
	}

実はこのステップは、接続を確立するときに途中でパラメータを切り取って、パラメータを削除して実行します.
フロントコード:
 window.CHAT = {
            socket: null,
            init: function() {
                if (window.WebSocket) {
                    CHAT.socket = new WebSocket("ws://127.0.0.1:8888/ws?token=  ");
                    CHAT.socket.onopen = function(event) {
                        console.log("      ...");
                    };
                            CHAT.socket.onclose = function(event) {
                                console.log("    ...");
                            };
                            CHAT.socket.onerror = function(event) {
                                console.log("    ...");
                                console.log(event);
                            };
                            CHAT.socket.onmessage = function(e) {
                                console.log("     " + e.data);
                                var receiveMsg = document.getElementById("receiveMsg");
                                var html = receiveMsg.innerHTML;
                                receiveMsg.innerHTML = html + "
" + e.data; }; } else { alert(" websocket ..."); } }, chat: function() { var msg = document.getElementById("msgContent"); CHAT.socket.send(msg.value); } }; CHAT.init();