脚穿拖鞋闯世界 發表於 2021-6-30 16:04:00

基于Node.js实现WebSocket 服务器

<p>From:WebSocket</p>
<h2>WebSocket</h2>
<p>WebSocket是HTML5新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的<strong>双向通信的通道</strong>,比如说,服务器可以在任意时刻发送消息给浏览器。任何一方都可以主动发消息给对方。</p>
<p>HTTP协议是一个请求-响应协议,请求必须先由浏览器发给服务器,服务器才能响应这个请求,再把数据发送给浏览器。换句话说,浏览器不主动请求,服务器是没法主动发数据给浏览器的。</p>
<h2>WebSocket协议</h2>
<p>WebSocket并不是全新的协议,而是利用了HTTP协议来建立连接。我们来看看WebSocket连接是如何创建的。</p>
<p>首先,WebSocket连接必须由浏览器发起,因为请求协议是一个标准的HTTP请求,格式如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">GET ws://localhost:3000/ws/chat HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Origin: http://localhost:3000
Sec-WebSocket-Key: client-random-string
Sec-WebSocket-Version: 13</span></pre>
</div>
<p>该请求和普通的HTTP请求有几点不同:</p>
<ol>
<li>GET请求的地址不是类似<code>/path/</code>,而是以<code>ws://</code>开头的地址;</li>
<li>请求头<code>Upgrade: websocket</code>和&nbsp;<code>Connection: Upgrade</code>表示这个连接将要被转换为WebSocket连接;</li>
<li><code>Sec-WebSocket-Key</code>是用于标识这个连接,并非用于加密数据;</li>
<li><code>Sec-WebSocket-Version</code>指定了WebSocket的协议版本。</li>
</ol>
<p>随后,服务器如果接受该请求,就会返回如下响应:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: server-random-string</span></pre>
</div>
<p>该<span style="color: rgba(255, 0, 0, 1)">响应代码<code>101</code></span>表示本次连接的HTTP协议即将被更改,更改后的协议就是<code>Upgrade: websocket</code>指定的WebSocket协议。</p>
<p>版本号和子协议规定了双方能理解的数据格式,以及是否支持压缩等等。如果仅使用WebSocket的API,就不需要关心这些。</p>
<p>现在,一个WebSocket连接就建立成功,浏览器和服务器就可以随时主动发送消息给对方。<strong>消息有两种,一种是文本,一种是二进制数据</strong>。通常,我们可以发送JSON格式的文本,这样,在浏览器处理起来就十分容易。</p>
<p><strong>为什么WebSocket连接可以实现全双工通信而HTTP连接不行呢?</strong></p>
<p>实际上HTTP协议是建立在TCP协议之上的,TCP协议本身就实现了全双工通信,但是HTTP协议的请求-应答机制限制了全双工通信。<span style="color: rgba(255, 0, 0, 1)">WebSocket连接建立以后,其实只是简单规定了一下:接下来,咱们通信就不使用HTTP协议了,直接互相发数据吧。</span></p>
<p>安全的WebSocket连接机制和HTTPS类似:</p>
<p>首先,浏览器用<code>wss://xxx</code>创建WebSocket连接时,会先通过HTTPS创建安全的连接,然后,该HTTPS连接升级为WebSocket连接,底层通信走的仍然是安全的SSL/TLS协议。</p>
<h2>浏览器</h2>
<p>很显然,要支持WebSocket通信,浏览器得支持这个协议,这样才能发出<code>ws://xxx</code>的请求。目前,支持WebSocket的主流浏览器如下:</p>
<ul>
<li>Chrome</li>
<li>Firefox</li>
<li>IE &gt;= 10</li>
<li>Sarafi &gt;= 6</li>
<li>Android &gt;= 4.4</li>
<li>iOS &gt;= 8</li>
</ul>
<h2>服务器</h2>
<p>由于WebSocket是一个协议,服务器具体怎么实现,取决于所用编程语言和框架本身。Node.js本身支持的协议包括TCP协议和HTTP协议,要支持WebSocket协议,需要对Node.js提供的HTTPServer做额外的开发。已经有若干基于Node.js的稳定可靠的WebSocket实现,我们直接用npm安装使用即可。</p>
<h2>使用ws实现</h2>
<p><strong>要使用WebSocket,关键在于服务器端支持,这样,我们才有可能用支持WebSocket的浏览器使用WebSocket</strong>。</p>
<p>ws模块</p>
<p>在Node.js中,使用最广泛的WebSocket模块是<code>ws</code></p>
<p>使用</p>
<p>1、创建文件夹</p>
<p>2、npm init -y&nbsp; &nbsp;创建package.json</p>
<p>3、安装 ws模块: npm i ws</p>
<p>4、添加index.js 编写webSocket服务端代码</p>
<div class="cnblogs_code">
<pre>const WebSocket = require('ws'<span style="color: rgba(0, 0, 0, 1)">)

const WebSocketServer </span>=<span style="color: rgba(0, 0, 0, 1)"> WebSocket.Server;

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">在4000端口上打开了一个WebSocket Server,该实例由变量wss引用。</span>
const wss =<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> WebSocketServer({
    port:</span>4000<span style="color: rgba(0, 0, 0, 1)">
})

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">如果有WebSocket请求接入,wss对象可以响应connection事件来处理这个WebSocket:</span>
wss.on('connection',<span style="color: rgba(0, 0, 255, 1)">function</span>(ws){<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">在connection事件中,回调函数会传入一个WebSocket的实例,表示这个WebSocket连接。</span>
<span style="color: rgba(0, 0, 0, 1)">    console.log(` connection()`);
    ws.on(</span>'message',<span style="color: rgba(0, 0, 255, 1)">function</span>(message){<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">我们通过响应message事件,在收到消息后再返回一个ECHO: xxx的消息给客户端。</span>
<span style="color: rgba(0, 0, 0, 1)">      console.log(` Received:${message}`);
      ws.send(`ECHO:${message}` ,(err)</span>=&gt;<span style="color: rgba(0, 0, 0, 1)">{
            </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(err){
                console.log(` error:${err}`);
            }
      })
    })
})</span></pre>
</div>
<p>5、创建WebSocket连接</p>
<p>如何真正创建WebSocket并且给服务器发消息呢?方法是在浏览器中写JavaScript代码。</p>
<p>但是在浏览器console中写代码比较麻烦,</p>
<p><code>其实ws</code>模块既包含了服务器端,又包含了客户端。<code>ws</code>的<code>WebSocket</code>就表示客户端,它其实就是WebSocketServer响应<code>connection</code>事件时回调函数传入的变量<code>ws</code>的类型。</p>
<p>编写客户端代码 client.js:</p>
<div class="cnblogs_code">
<pre>const WebSocket =require('ws'<span style="color: rgba(0, 0, 0, 1)">)
let ws </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> WebSocket('ws://localhost:4000/test'<span style="color: rgba(0, 0, 0, 1)">);

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 打开WebSocket连接后立刻发送一条消息:</span>
ws.on('open', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
    console.log(` open()`);
    ws.send(</span>'Hello!'<span style="color: rgba(0, 0, 0, 1)">);
});

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 响应收到的消息:</span>
ws.on('message', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (message) {
    console.log(` Received: ${message}`);
})</span></pre>
</div>
<p>执行:node client.js</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/peterYong/p/14954937.html
頁: [1]
查看完整版本: 基于Node.js实现WebSocket 服务器