前面的 socket.io
使用原生 JS 来写 Demo,这边就试着改用框架来处理,不过毕竟目前还是 Demo 练习性质,所以就直接用 CDN 引入,不使用 cli,至於版本的部分,暂时先用 2.6 版。
先用 script 引入 cdn,再使用 app 去包,每一则讯息的渲染则是透过 v-for
放在 li
标签上,省了 innerHTML
的书写。
input
透过 v-model
双向绑定输入的值,button
不用透过 DOM 操作,可以直接使用 click 事件来触发 function。
client / index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
</head>
<body>
<div id="app">
<input type="text" class="input-message" v-model="message" />
<button type="button" class="send-btn" @click="sendMessage()">
Send Message
</button>
<ul class="message-wrapper">
<li v-for="(item, index) in list" :key="index + item">{{ item }}</li>
</ul>
</div>
<script src="./client.js"></script>
</body>
</html>
把原本的 DOM 操作通通拔掉,也不需要额外写 addEventListener()
。
list
是用来存放讯息的阵列,所以当使用者送出输入的讯息时,列表即会更新变化,在 sendMessage()
触发,但对其他使用来说,他必须等到 server-side 转发讯息回来,再透过 onMessage()
监听的方式,触发列表变化,这是流程上两者的差异。
client / client.js
const app = new Vue({
el: '#app',
data: {
list: [],
message: '',
ws: {},
},
mounted() {
this.ws = new WebSocket('ws://127.0.0.1:3000');
this.ws.onopen = this.onOpen;
this.ws.onmessage = this.onMessage;
this.ws.onclose = this.onClose;
this.ws.onerror = this.onError;
},
methods: {
onOpen() {
console.log(`open : ${this.ws.readyState}`);
},
onMessage(event) {
this.list.push(event.data);
},
onClose() {
console.log(`close : ${this.ws.readyState}`);
},
onError() {
console.log(`error : ${this.ws.readyState}`);
},
sendMessage() {
this.list.push(this.message);
this.ws.send(this.message);
this.message = '';
},
},
});
server-side 在转发讯息时,需要先确认两件事,因为广播事件是传递给目前线上的所有使用者,所以第一个需要先过滤掉讯息发送者。举例来说:
A, B 两个玩家同时登入在线上,A 玩家送出讯息 Hello all!
,自然系统不需要对 A 玩家发出这则讯息,仅需要通知 B 玩家,反之,B 玩家送出讯息时也是同理。
第二个则是确认该玩家是否断线,所以透过 readyState 的值来检查是否符合 WebSocket 保持连线的值,确认目前的玩家列表中,那些人仍维持上线状态,并只针对这些人发送讯息。
server / server.js
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 3000 });
wss.on('connection', function connection(ws) {
ws.on('message', function (message) {
const bufferMessage = Buffer.from(message).toString();
wss.clients.forEach((client) => {
if (ws !== client && client.readyState === WebSocket.OPEN) {
client.send(bufferMessage);
}
});
});
});
<<: D24 - 「不断线的侏罗纪」:天上好多云、地上一堆仙人掌
场景与需求 APP跟网页一样,要被下载,最容易的办法就是要取得流量大的关键字的上位排名,也就是要做S...
元件介绍 Tooltip 是一个文字弹出提醒元件,当 active 状态时,会显示对该子元件描述的文...
本篇文章同步发表在 HKT 线上教室 部落格,线上影音教学课程已上架至 Udemy 和 Youtu...
工程师太师了: 第4.5话 杂记: 索引 (index) 索引是用以识别阵列各元素的符号,阵列中每个...
演算法评估 ### 演算法衡量 效率 渐进符号 EX:O(n) 最差案例 平均案例 平摊分析 问题衡...