WebSocket是一种用于在服务器与客户端之间实现高效的双向通讯的机制。能够解决数据实时性要求比较高的应用,好比:在线聊天,在线教育,炒股或定位等。html
一:websocket产生背景:node
为了解决这种实时性的问题,有几种替代方案:web
一、轮询json
概念:客户端经过必定的时间间隔以频繁请求的方式向服务器发送请求,来保持客户端和服务器端的数据同步;api
缺点:当客户端以固定频率向服务器端发送请求时,服务器端的数据可能并无更新,带来不少无谓请求,浪费带宽,效率低下浏览器
二、Comet技术(长轮询)服务器
概念:长轮询在客户端发送请求后,服务器保留响应,并维持链接,能够在任意时间点从服务器返回响应。而客户端在收到响应的同时再次向服务器创建链接。实例:WebQQwebsocket
缺点:与轮询相比,长轮询避免了没必要要的通讯过程,但也须要在有更新时再次链接网络
三、Comet技术(流技术)app
概念:经过由客户端发出第一个请求,创建链接,并在维持该链接的同时从服务器不断向客户端返回响应
缺点:服务器维护一个长链接会增长开销
传统实时性技术的通讯数据流以下图:
二:websocket的运行机制
一、WebSocket只有在创建握手链接的时候借用了HTTP协议的头,链接成功后的通讯部分都是基于TCP的链接,它与 HTTP 之间的惟一关系就是它的握手请求能够做为一个升级请求(Upgrade request)经由 HTTP 服务器解释
二、WebSocket 请求响应客户端服务器交互图
只通过一次握手便可进行双向通讯。
三、WebSocket 协议优势:
1. Header
互相沟通的Header是很小的-大概只有 2 Bytes
2. Server Push
服务器的推送,服务器再也不被动的接收到浏览器的请求以后才返回数据,而是在有新数据时就主动推送给浏览器
4.websocket的api
websocket中有两个方法:
一、send() 向远程服务器发送数据
二、close() 关闭该websocket连接
websocket同时还定义了几个监听函数
一、onopen 当网络链接创建时触发该事件
二、onerror 当网络发生错误时触发该事件
三、onclose 当websocket被关闭时触发该事件
四、onmessage 当websocket接收到服务器发来的消息的时触发的事件,也是通讯中最重要的一个监听事件。
五、websocket还定义了一个readyState属性:
一、CONNECTING(0) websocket正尝试与服务器创建链接
二、OPEN(1) websocket与服务器已经创建链接
三、CLOSING(2) websocket正在关闭与服务器的链接
四、CLOSED(3) websocket已经关闭了与服务器的链接
简单的客户端与服务器通讯的案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>webSocket示例</title> </head> <body> <h1>Echo Test</h1> <input id="sendTxt" type="text" /> <button id="sendBtn">发送</button> <div id="recv"></div> <script> //建立websocket实例 var websocket=new WebSocket('ws://echo.websocket.org'); //‘ws://echo.websocket.org’是websocket测试的服务器,把你的数据原封不动的返回给你 //创建链接后的事件 websocket.onopen=function(){ console.log('websocket open'); document.getElementById('recv').innerHTML='Connected'; } //关闭链接 websocket.onclose==function(){ console.log('websocket close'); } //客户端接收到数据触发 websocket.onmessage=function(e){ console.log(e.data); document.getElementById('recv').innerHTML=e.data; } //点击发送按钮触发 document.getElementById('sendBtn').onclick=function(){ var txt=document.getElementById('sendTxt').value; document.getElementById('recv').innerHTML=txt; } </script> </body> </html>
直接浏览器打开文件,便可运行。
按F12观察一下
协议是ws协议,且状态是101正在链接的状态。
4、下面是制做一个简单聊天室功能
须要nodejs做服务器后台
package.json文件(下载nodejs-websocket模块)
{ "name": "demo2", "version": "1.0.0", "description": "", "main": "wsServer.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "nodejs-websocket": "^1.7.1" } }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>webSocket示例</title> </head> <body> <h1>Echo Test</h1> <input id="sendTxt" type="text" /> <button id="sendBtn">发送</button> <div id="recv"></div> <script> var websocket=new WebSocket('ws://localhost:8001/'); function showMessage(str){ var div=document.createElement('div'); div.innerHTML=str; document.body.appendChild(div); } //创建链接 websocket.onopen=function(){ console.log('websocket open'); document.getElementById('sendBtn').onclick=function(){ var txt=document.getElementById('sendTxt').value; if(txt){ websocket.send(txt); //发送数据给服务器 } } } //关闭链接 websocket.onclose==function(){ console.log('websocket close'); } //客户端接收数据触发 websocket.onmessage=function(e){ console.log(e.data); showMessage(e.data); } </script> </body> </html>
wsServer.js
var ws = require("nodejs-websocket"); var clientCount=0; var server = ws.createServer(function (conn) { console.log("New connection") clientCount++; conn.nickname='user'+clientCount; boradcast(conn.nickname+' comes in'); //服务端接收到消息后触发 conn.on("text", function (str) { boradcast(conn.nickname+' says: '+str); }) //关闭链接 conn.on("close", function (code, reason) { console.log("Connection closed"); boradcast(conn.nickname+' left'); }) // conn.on("error",function(err){ console.log("handle err"); console.log(err); }) }).listen(8001); function boradcast(str){ server.connections.forEach(function(connection){ connection.sendText(str); }) }
运行node wsServer.js
运行node以后,直接打开浏览器浏览文件,一个文件表明一个用户,这样就能够两边对话了。
这个h5的新协议仍是颇有趣的。
推荐去看一下:http://www.imooc.com/learn/861 websocket案例讲解。