赞
踩
Websocket:
Websocket是HTML5新增加的协议,在服务器与浏览器之间建立一个不受限的双向通道,可以实现服务器主动向浏览器推送消息。
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不是read0)
- @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 + "\n" + e.data;
- };
-
- } else {
- alert("浏览器不支持websocket协议...");
- }
- },
- chat: function() {
- var msg = document.getElementById("msgContent");
- CHAT.socket.send(msg.value);
- }
- };
-
- CHAT.init();
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。