介绍
WebSocke 是HTML5所新定义的协议,适用于频繁交互消息的场景,比如图表更新、聊天室和web游戏等。首先WebSocket的出现为了解决在频繁交互消息场景下,使用HTTP消耗资源过大的问题。在WebSocket还没出现时,只能使用轮询或者长轮询来不断请求服务端获取数据。轮询既是通过Ajax设定一段时间去请求服务端,服务端返回后,又立即发送请求。而长轮询是发送请求到服务端后,请求阻塞,直到服务端返回消息,整个请求过程才算结束,但是结束后又会立即请求服务端等待获取数据。无论是用哪种轮询,都必须发出多次的HTTP请求,我们知道,发出HTTP是消耗资源的。而且每次的HTTP请求头都重复很多无用的数据,这就是HTTP的缺点,并且不能主动从服务端推送消息到客户端。
WebSocket建立连接时的握手阶段也是通过HTTP协议的,类似HTTP的三次握手,只不过它只握了两次。以下是WebSocket请求头:
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.9
Cache-Control:no-cache
Connection:Upgrade
Cookie:JSESSIONID=8130578A45241D945F3202B9C98809FB; _ga=GA1.1.1329605173.1521959310
Host:localhost:8080
Origin:http://localhost:8080
Pragma:no-cache
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
Sec-WebSocket-Key:HplGjYoX3yyYPR1+PZhW2g==
Sec-WebSocket-Version:13
Upgrade:websocket
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36
其中Upgrade:websocket
是告诉服务器需要使用的WebSocket协议来执行,Sec-WebSocket-Key
是一个Base64编码的值,由浏览器随机生成,用来验证返回时是否是当前这个请求的返回。Sec-WebSocket-Version
是的WebSocket的版本,指明当前请求的版本,提示服务端也需要用相同的版本建立连接。接着,服务端返回一个响应:
Connection:upgrade
Date:Mon, 09 Jul 2018 11:25:30 GMT
Sec-WebSocket-Accept:sxwESjBHtN0/KArRr/qV3J6Livc=
Sec-WebSocket-Extensions:permessage-deflate;client_max_window_bits=15
Server:Apache-Coyote/1.1
Upgrade:websocket
Upgrade:websocket
代表当前就是使用WebSocket来和你建立连接,Sec-WebSocket-Accept
返回的是请求时的Sec-WebSocket-Accept
字符串经过确认后加密的的字符。一切完成后,服务端就可以自由的推送消息到客户端,客户端也可以发送消息到服务端,达到双向通信啦。
使用
因为WebSocket是HTML5的协议,想要使用就必须要在支持HTML5的浏览器中运行。如果不支持,又或者想兼容其他不支持的浏览器而想要达到相同的效果,轮询了解下。以下是JS 操作WebSocket的基本方法:
建立连接
var ws = new WebSocket('ws://localhost:8080');
指定连接成功后的回调函数
ws.onopen = function(){
ws.send('Hello Server!');
}
关闭连接,注意:关闭浏览器时不关闭连接服务端可能报错
ws.close(); //关闭连接
//浏览器关闭的同时关闭连接
window.onbeforeunload = function(){
ws.close();
}
指定连接关闭后的回调函数
ws.onclose = function (event) {
var code = event.code;
var reason = event.reason;
var wasClean = event.wasClean;
//处理关闭事件
};
指定收到服务器数据后的回调函数
ws.onmessage = function (event){
var data = event.data;
console.log(data);
//处理数据
};
向服务器发送数据
ws.send('你的消息');
这几个方法应该满足日常的使用需求了。
实例
本例使用java和websocket实现了一个手机摇一摇的游戏,玩法是首先建立房间,手机通过扫码进入房间,每个房间限制人数为两个。待两人都进入房间后,游戏开始,玩家需要不停摇动手机来使得进度条达到100%,谁先达到谁就胜出。效果图如下:
整个游戏的玩法很简单,但是想用Ajax来实现,麻烦得要死。这里就不贴代码了,具体请看连接。
github:https://github.com/xiolovelife/WebSocketTest
参考:
https://blog.csdn.net/yinqingwang/article/details/52565133
http://www.ruanyifeng.com/blog/2017/05/websocket.html