Vue+Nodejs 实现websocket
<p><strong>ajax 轮询</strong>:让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息
<strong>
long poll 长轮询</strong>:其实原理跟 ajax轮询 差不多,都是采用轮询的方式,不过采取的是阻塞模型(一直打电话,没收到就不挂电话),也就是说,客户端发起请求后,如果没消息,就一直不返回 Response 给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。</p>
<p>这两种方式,都是在不断地建立HTTP连接,然后等待服务端处理,可以体现HTTP协议的另外一个特点,被动性。服务端不能主动联系客户端,只能有客户端发起。上面这两种都是非常消耗资源的。</p>
<hr />
<p><strong>websocket:</strong>它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
<img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=1b06186374c4933dd8467b9370e57dd5" alt="" /></p>
<p>node:</p>
<pre><code class="language-javascript">app.js
const webSocketService = require('./websocketservice')
webSocketService.listen()</code></pre>
<pre><code class="language-javascript">websocketservice.js
const WebSocket = require('ws');
// 创建WebSocket服务端的对象,端口号是3001
const wss = new WebSocket.Server({
port: 3001,
});
// 服务端开启了监听
module.exports.listen = () => {
// client是客户端的连接socket对象
wss.on('connection', client => {
console.log('有客户端连接成功了');
// 对客户端的每10秒推送
setInterval(() => {
client.send('这是服务端的定期推送(每5s)');
}, 5000);
// msg是客户端发给服务端的数据
client.on('message', msg => {
console.log('客户端发送数据给服务端了:', JSON.parse(msg));
client.send('不借');
});
});
};</code></pre>
<p>Vue:</p>
<pre><code class="language-javascript">组件.vue
<template>
<button @click="sendData">ws</button>
<router-view />
</template>
<script setup lang="ts">
import SocketService from '@/websocket';
const data = {
socketServe: SocketService.Instance,
};
SocketService.Instance.connect();
data.socketServe = SocketService.Instance;
const sendData = () => {
data.socketServe.send('借我100元');
};
</script></code></pre>
<pre><code class="language-javascript">websocket.js
export default class SocketService {
static instance = null;
static get Instance() {
if (!this.instance) {
this.instance = new SocketService();
}
return this.instance;
}
// 和服务端连接的socket对象
ws = null;
// 标识是否连接成功
connected = false;
// 重新连接尝试的次数
connectRetryCount = 0;
// 连接
connect() {
let url = 'ws://localhost:3001';
this.ws = new WebSocket(url, 'echo-protocol');
// 连接成功的事件
this.ws.onopen = () => {
console.log('连接服务端成功了');
this.connected = true;
// 重置重新连接的次数
this.connectRetryCount = 0;
};
// 连接失败的事件
this.ws.onclose = () => {
this.connected = false;
this.connectRetryCount++;
console.log(`连接服务端失败,已连接${this.connectRetryCount}次`);
//每3s重新自动连接一次
setTimeout(() => {
this.connect();
}, 3000)
};
// 接收服务端发送过来的数据
this.ws.onmessage = msg => {
console.log(`从服务端获取到了数据:${msg.data}`);
};
}
// 发送数据的方法
send(data) {
if (this.connected) {
this.ws.send(JSON.stringify(data));
} else {
console.log('发送失败')
}
}
}</code></pre>
<p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=8fdb1881f5d946a8b43cf8b5841c4fa0" alt="" /></p>
<p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=3f3b436501172dc819eeb4ca8c910547" alt="" /></p>
<p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=69e63a9701e1433288d75489563bb2df" alt="" /></p>