對于聊天室,大家應該都不陌生,筆者也寫過很多關于聊天室的例子。
本節,我們将示範如何通過Node.js來實作一個WebSocket聊天伺服器的例子。
使用ws建立WebSokcet伺服器
Node.js原生API并未提供WebSocket的支援,是以,需要安裝第三方包才能使用WebSocket功能。對于WebSocket的支援,在開源社群有非常多的選擇,本例子采用的是“ws”架構(項目首頁為
https://github.com/websockets/ws)。
“ws”顧名思義是一個用于支援WebSocket用戶端和伺服器的架構。它易于使用,功能強大,且不依賴于其他環境。
想其他Node.js應用一樣,使用ws的首選方式是使用npm來管理。以下指令行用于安裝ws在應用裡面:
npm install ws
具備了ws包之後,就可以建立WebSocket伺服器了。以下是建立伺服器的j簡單示例:
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });
上述例子伺服器啟動在8080端口。
聊天伺服器的需求
聊天伺服器的業務需求比較簡單,是一個群聊聊天室。換言之,所有人發送的消息大家都可以見到。
當有新使用者連接配接到伺服器時,會以該使用者的“IP+端口”作為使用者的名稱。
伺服器的實作
根據前面知識的學習,實作一個聊天伺服器比較簡單,完整代碼如下:
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });
server.on('open', function open() {
console.log('connected');
});
server.on('close', function close() {
console.log('disconnected');
});
server.on('connection', function connection(ws, req) {
const ip = req.connection.remoteAddress;
const port = req.connection.remotePort;
const clientName = ip + port;
console.log('%s is connected', clientName)
// 發送歡迎資訊給用戶端
ws.send("Welcome " + clientName);
ws.on('message', function incoming(message) {
console.log('received: %s from %s', message, clientName);
// 廣播消息給所有用戶端
server.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send( clientName + " -> " + message);
}
});
});
});
當用戶端給伺服器發送消息時,伺服器會将該用戶端的消息轉發給所有用戶端。
用戶端的實作
用戶端是通HTML+JavaScript的方式實作的。由于浏覽器原生提供了WebSocket的API,是以并不需要ws架構的支援。
用戶端client.html檔案代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WebSocket Chat</title>
</head>
<body>
<script type="text/javascript">
var socket;
if (!window.WebSocket) {
window.WebSocket = window.MozWebSocket;
}
if (window.WebSocket) {
socket = new WebSocket("ws://localhost:8080/ws");
socket.onmessage = function (event) {
var ta = document.getElementById('responseText');
ta.value = ta.value + '\n' + event.data
};
socket.onopen = function (event) {
var ta = document.getElementById('responseText');
ta.value = "連接配接開啟!";
};
socket.onclose = function (event) {
var ta = document.getElementById('responseText');
ta.value = ta.value + "連接配接被關閉";
};
} else {
alert("你的浏覽器不支援 WebSocket!");
}
function send(message) {
if (!window.WebSocket) {
return;
}
if (socket.readyState == WebSocket.OPEN) {
socket.send(message);
} else {
alert("連接配接沒有開啟.");
}
}
</script>
<form onsubmit="return false;">
<h3>WebSocket 聊天室:</h3>
<textarea id="responseText" style="width: 500px; height: 300px;"></textarea>
<br>
<input type="text" name="message" style="width: 300px" value="Welcome to waylau.com">
<input type="button" value="發送消息" onclick="send(this.form.message.value)">
<input type="button" onclick="javascript:document.getElementById('responseText').value=''"
value="清空聊天記錄">
</form>
<br>
<br>
<a href="https://waylau.com/">更多例子請通路 waylau.com</a>
</body>
</html>
運作應用
首先啟動伺服器。執行下面的指令:
node index.js
接着用浏覽器直接打開client.html檔案,可以看到如下的聊天界面。

打開多個聊天視窗,就能模拟多個使用者之間的群聊了。
源碼
本節例子可以在
https://github.com/waylau/nodejs-book-samples的“ws-demo”應用中找到。
本節例子可以在“ws-demo”應用中找到。
參考引用
- 本文同步至: https://waylau.com/node.js-websocket-chat/
- MINA 實作聊天功能: https://waylau.com/mina-chat/
- Netty 實作 WebSocket 聊天功能: https://waylau.com/netty-websocket-chat/
- Netty 實作聊天功能: https://waylau.com/netty-chat/
- WebSocket 和 Golang 實作聊天功能: https://waylau.com/go-websocket-chat/