ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
>[success]总结: 1. websocket是h5独有的,是一个基于TCP协议,只需要一个握手动作,就通过js发送数据。状态码是1xx开头的,如101成功。 2. 服务端我使用的是纯php开发的框架:workerman。 3. 可参考我的“常见类库使用-》workerman”(参考之前千万要看完这篇文章,自己跑下代码试一下,这样你就会更明白) <br /> # :-: websocket WebSocket是HTML5开始提供的一种在<span style="color:red;">单个 TCP 连接上进行全双工通讯的协议</span>。 在WebSocket API中,浏览器和服务器<span style="color:red;">只需要做一个握手的动作</span>,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。 浏览器<span style="color:red;">通过 JavaScript </span>向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。 当你获取<span style="color:red;"> Web Socket 连接后</span>,你可以<span style="color:red;">通过 send() 方法来向服务器发送数据</span>,并<span style="color:red;">通过 onmessage 事件来接收服务器返回的数据</span>。 > Web套接字 - 定义 > Web套接字被定义为服务器和客户端之间的双向通信,这意味着双方同时进行通信和交换数据。 > Web套接字的<span style="color:red;">关键点</span>是真正的并发性和性能优化,从而产生更灵敏和更丰富的Web应用程序 # :-: 以下 API 用于创建 WebSocket 对象 ```js var Socket = new WebSocket(url, [protocol] ); #第一个参数,指定连接的 URL。第二个参数 protocol 是可选的,指定了可接受的子协议。 ``` ### **网址(url)** HTTP有自己的一组模式,如http和https。Web套接字协议也具有在其URL模式中定义的类似模式。 下图显示了令牌中的Web Socket URL。 ![](https://box.kancloud.cn/346c460e8be82ddde70807d49f0fdadb_501x106.png) 以下是 WebSocket 对象的<span style="color:blue;">属性</span>。假定我们使用了以上代码创建了 Socket 对象: ![](https://box.kancloud.cn/740c4540b3a595a855ef3dc83893cd53_732x301.png) 以下是 WebSocket 对象的相关<span style="color:blue;">事件</span>。假定我们使用了以上代码创建了 Socket 对象: ![](https://box.kancloud.cn/63fad569ebbfc884eb15a9812ea252e7_731x199.png) 以下是 WebSocket 对象的相关<span style="color:blue;">方法</span>。假定我们使用了以上代码创建了 Socket 对象: ![](https://box.kancloud.cn/6a99d886cfc9fc577ac0479a75b2921c_731x108.png) >[info]属性啥也不带;事件前,带on;方法后,带(); # :-: websocket的实例 WebSocket 协议本质上是一个<span style="color:red;">基于 TCP</span> 的协议。 为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,<span style="color:red;">包含了一些附加头信息,其中附加头信息"Upgrade: WebSocket"表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端</span>,客户端和服务器端的 WebSocket <span style="color:red;">连接就建立</span>起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在<span style="color:red;">直到客户端或者服务器端的某一方主动的关闭连接</span>。 ![](https://box.kancloud.cn/ba8706f73418b16a18e40283e6e69d56_1395x490.png) ## 1、代码可以参考这个卖书的网站:http://www.websocket.org/echo.html 也可以直接复制,粘贴到你自己的ide上 ``` html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试</title> </head> <body> <div id="output"></div> <script> var socket; var url = "ws://echo.websocket.org/"; //指定连接的url。真实项目中这里填写服务器的ip或域名 var output; //初始化 function init(){ output = document.getElementById('output'); testWebSocket(); } function testWebSocket() { socket = new WebSocket(url); //只需要做一个握手的动作,浏览器和服务器之间就形成了一条快速通道,就可以将数据互相传送了 //连接上服务端时触发 socket.onopen = function () { writeToScreen('连接'); doSend("websocket rocks"); }; //服务端断开时触发 socket.onclose = function(){ writeToScreen('关闭'); }; //接收服务端发来的请求 socket.onmessage = function(evt){ writeToScreen('<span style="color: blue;">RESPONSE: '+ evt.data+'</span>'); socket.close(); }; //通信发生错误时触发 socket.onerror = function (evt) { writeToScreen('<span style="color: red;">ERROR:</span> '+ evt.data); }; } //发送数据 function doSend(message){ writeToScreen('SENT:'+ message); //先显示 socket.send(message); //后发送 } //显示内容 function writeToScreen(message) { var pre = document.createElement('p'); pre.style.wordWrap = "break-word"; pre.innerHTML = message; output.appendChild(pre); //追加节点 } window.addEventListener("load", init, false); //加载,初始化函数 </script> </body> </html> ``` ## 2、主要代码解释: ### 2.1、申请一个WebSocket对象 参数是需要连接的服务器端的地址,同http协议使用http://开头一样,<span style="color:red;">WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头</span>。 ``` js var wsUri ="ws://echo.websocket.org/"; websocket = new WebSocket(wsUri); ``` ### 2.2、WebSocket对象一共支持四个消息 onopen, onmessage, onclose和onerror 我们可以看出所有的操作都是采用消息的方式触发的,这样就不会阻塞UI,使得UI有更快的响应时间,得到更好的用户体验。 (1)当Browser和WebSocketServer连接成功后,会触发onopen消息; ``` js websocket.onopen = function(evt) {}; ``` (2)如果连接失败,发送、接收数据失败或者处理数据出现错误,browser会触发onerror消息; ``` js websocket.onerror = function(evt) { }; ``` (3)当Browser接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,参数evt中包含server传输过来的数据; ``` js websocket.onmessage = function(evt) { }; ``` (4)当Browser接收到WebSocketServer端发送的关闭连接请求时,就会触发onclose消息。 ``` js websocket.onclose = function(evt) { }; ``` ### 2.3、通信协议 WebSocket与TCP、HTTP的关系WebSocket与http协议一样都是基于TCP的,所以他们都是可靠的协议,Web开发者调用的WebSocket的send函数在browser的实现中最终都是通过TCP的系统接口进行传输的。 &nbsp; WebSocket和Http协议一样都属于应用层的协议,那么他们之间有没有什么关系呢?答案是肯定的,<span style="color:red;">WebSocket在建立握手连接时,数据是通过http协议传输的</span>,但是在建立连接之后,真正的数据传输阶段是不需要http协议参与的。 ![](https://box.kancloud.cn/d79b568c64098a45f037c107bb214a73_536x229.png) ### 2.4、通讯协议详解 从下图可以明显的看到,分三个阶段: 1. 打开握手 2. 数据传递 3. 关闭握手 ![](https://box.kancloud.cn/cb45dbabcf7cbf4264342217ebd3074d_544x524.png) 下图显示了WebSocket主要的三步 浏览器和 服务器端分别做了那些事情 ![](https://box.kancloud.cn/c359d84badf60138ea72280794328c60_601x448.png) ### 2.5、WebSocket的优点 1. 服务器与客户端之间交换的标头信息很小,大概只有2字节; 2. 客户端与服务器都可以主动传送数据给对方; 3. <span style="color:red;">不用频率创建TCP请求及销毁请求</span>,减少网络带宽资源的占用,同时也节省服务器资源; ### 2.6、建立连接的握手 <span style="color:red;">当Web应用程序调用</span>new WebSocket(url)接口时,Browser就开始了与地址为url的WebServer<span style="color:red;">建立握手连接的过程</span>。 1. Browser与WebSocket服务器通过TCP三次握手建立连接,如果这个建立连接<span style="color:red;">失败</span>,那么<span style="color:red;">后面的过程就不会执行</span>,Web应用程序将收到错误消息通知。 2. 在TCP建立连接成功后,<span style="color:red;">Browser/UA通过</span>http协议<span style="color:red;">传送</span>WebSocket支持的版本号,协议的字版本号,原始地址,主机地址等等一些列字段给服务器端。 3. WebSocket服务器<span style="color:red;">收到</span>Browser/UA发送来的握手请求后,<span style="color:red;">如果</span>数据包数据和格式<span style="color:red;">正确</span>,客户端和服务器端的协议版本号匹配等等,就<span style="color:red;">接受本次握手连接</span>,并给出相应的数据回复,同样回复的数据包也是采用http协议传输。 4. <span style="color:red;">Browser收到服务器回复的数据包</span>后,如果数据包内容、格式都没有问题的话,就表示本次连接成功,<span style="color:red;">触发onopen消息</span>,此时Web开发者就可以在此时<span style="color:red;">通过send接口想服务器发送数据</span>。否则,握手连接失败,Web应用程序会收到onerror消息,并且能知道连接失败的原因。 这个<span style="color:red;">握手很像HTTP,但是实际上却不是</span>,它允许服务器以HTTP的方式解释一部分handshake的请求,然后切换为websocket ### 2.7、数据传输 - WebScoket协议中,数据以帧序列的形式传输。 - 考虑到数据安全性,客户端向服务器传输的数据帧必须进行掩码处理。服务器若接收到未经过掩码处理的数据帧,则必须主动关闭连接。 - 服务器向客户端传输的数据帧一定不能进行掩码处理。客户端若接收到经过掩码处理的数据帧,则必须主动关闭连接。 - 针对上情况,发现错误的一方可向对方发送close帧(<span style="color:red;">状态码是1002,表示协议错误</span>),以关闭连接。 - 关闭WebSocket(握手) ![](https://box.kancloud.cn/69ece4d8be40fc95d4363d160bb20d25_523x240.png)