1. 程式人生 > >Node.js實現WebSocket聊天室的例子

Node.js實現WebSocket聊天室的例子

對於聊天室,大家應該都不陌生,筆者也寫過很多關於聊天室的例子。

本節,我們將演示如何通過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”應用中找到。

參考引用