Netty-socketio簡介
1. 簡介
在本文中,我們將了解Netty-socketio 庫。我們將探索它的含義,並了解如何使用它來建立與 Web 應用程式通訊的Socket.IO服務。
2.什麼是Socket.IO?
Socket.IO 是一個 JavaScript 函式庫,它使應用程式能夠在瀏覽器和後端伺服器之間建立低延遲、雙向、基於事件的通訊。通常,這是使用WebSockets實現的,不過 Socket.IO 函式庫也支援較新的WebTransport API ,或是在需要時回退到 HTTP 長輪詢。
我們可以使用 Socket.IO 函式庫來抽象化底層傳輸,從而更輕鬆地處理程式碼中的通訊。然而,它的作用遠不止於此。它保證訊息按順序傳遞,即使在不可靠的網路連線下也會盡力傳遞訊息。
在伺服器內部,Socket.IO 會自動管理連線-為每個連線分配一個唯一的 ID。這樣,我們就可以向連線的另一端發送命名事件,接收端也可以根據事件名稱了解如何處理該事件。
我們也可以將事件拆分成多個「房間」。這些房間是服務中可以存在的任意通道,讓我們能夠輕鬆地一次與所有客戶端進行溝通。
3. 設定 Netty-Socketio
Netty-Socketio 是一個 Java 函式庫,它使用 Netty 網路伺服器來運行一個可以處理 Socket.IO 連線的網路伺服器。我們可以將其用作 Socket.IO 用戶端進行通訊的後端。
3.1. 依賴項
要使用此功能,我們需要在建置中包含最新版本,目前版本為 2.0.13 。
如果我們使用 Maven,我們可以在pom.xml
檔案中包含此依賴項:
<dependency>
<groupId>com.corundumstudio.socketio</groupId>
<artifactId>netty-socketio</artifactId>
<version>2.0.13</version>
</dependency>
此時,我們已準備好開始在我們的應用程式中使用它。
3.2. 建立網路伺服器
新增依賴項後,我們需要為 Socket.IO 流量建立一個網路伺服器。 Netty -socketio 的工作原理是創建一個全新的網頁伺服器,這意味著即使我們的應用程式中沒有其他伺服器(例如,如果我們沒有運行 Tomcat 之類的 Web 伺服器),我們也可以使用它。但是,這也意味著,如果我們在 Web 應用中使用它,則需要監聽不同的連接埠。
我們需要做的第一件事是創建我們的伺服器配置:
Configuration config = new Configuration();
config.setHostname("localhost");
config.setPort(8081);
這會告訴 Netty-socketio 運行伺服器的主機和連接埠。
然後我們可以使用它來建構 Socket IO 伺服器的實例:
SocketIOServer server = new SocketIOServer(config);
最後,我們可以啟動伺服器運行:
server.start();
至此,我們的伺服器可以處理 Socket.IO 連線了。不過,我們暫時還不需要對它們做任何事。
3.3. 連接到我們的伺服器
除了伺服器之外,我們還需要一個可以連接到伺服器的 Socket.IO 用戶端。通常,這意味著在我們的 Web 瀏覽器中執行程式碼。
Socket.IO 用戶端庫可以從 CDN 中包含,如下所示:
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.8.1/socket.io.js"></script>
然後我們可以使用它來連接到我們的伺服器:
// JavaScript
const socket = io("ws://localhost:8081");
這將為我們提供與 Socket.IO 伺服器的活動連接,然後我們可以使用它與後端進行通訊。
4.處理事件
一旦網路伺服器正常運作,我們就需要能夠對事件做出回應。為此,我們需要為我們感興趣的事件註冊事件監聽器。
首先,我們可以註冊事件監聽器,這樣當有新客戶端連線或現有客戶端斷開連線時就會收到通知:
server.addConnectListener(client -> {
LOG.info("New connection from client {}", client.getRemoteAddress());
});
server.addDisconnectListener(client -> {
LOG.info("Disconnection from client {}", client.getRemoteAddress());
});
這些方法呼叫時會傳入一個SocketIOClient
實例,表示與特定客戶端的連線。我們可以使用它來查詢連接詳情,甚至與客戶端進行通訊。
除此之外,我們還可以註冊監聽客戶端發送給我們的任意事件的監聽器:
server.addEventListener("message", String.class, (client, message, request) -> {
LOG.info("Received message from client {}: {}", client.getRemoteAddress(), message);
});
事件名稱必須與傳送代碼中使用的名稱相符:
// JavaScript
socket.emit('message', message);
這樣,我們就可以針對不同類型的事件註冊不同的處理程序,然後客戶端就可以根據需要發送這些不同的事件。
5.發送訊息
現在我們可以接收從客戶端發送的訊息,我們還需要能夠將訊息發送回客戶端。
只要我們獲得了一個客戶端的參考(例如,一個適當的SocketIOClient
實例),我們就可以使用它來向客戶端發送事件。這個引用的來源並不重要——例如,它是對傳入事件的回應,還是我們之前儲存了它以備後用。唯一重要的是客戶端仍然處於連線狀態。
我們使用sendEvent()
方法來管理這一點,並取得要傳送的事件的名稱和有效負載:
client.sendEvent("message", payload);
與普通的 HTTP 處理程序不同,我們無需在收到訊息時執行此操作。我們可以隨時根據所需的觸發器向任何客戶端發送訊息。我們只需要一個對客戶端的引用和一個活動的連結。
6. 房間
除了處理單一客戶端之外,Socket.IO 還提供了「房間」的概念。房間是一種將多個客戶端分組到同一個房間名稱下的方法。完成後,我們就可以將它們視為一個整體來處理。
我們可以使用SocketIOClient.joinRoom()
方法將客戶端加入房間:
client.joinRoom("testroom");
然後我們可以使用SocketIOClient.leaveRoom()
方法從房間中移除客戶端:
client.leaveRoom("testroom");
當客戶端斷開連線時,它們也會自動從所有房間中刪除,因此我們無需手動進行管理。
客戶可以根據需要加入任意數量的房間,並且將客戶添加到一個房間不會影響他們在其他房間的會員資格。
然後,我們可以透過取得指定房間的BroadcastOperations
物件的引用來與整個房間互動。這可以透過SocketIOServer
實例完成,也可以透過任何SocketIOClient
實例間接完成:
BroadcastOperations room = server.getRoomOperations("testroom");
BroadcastOperations room = client.getNamespace().getRoomOperations("testroom");
這樣,我們就可以向整個房間發送事件,而不僅僅是單一客戶端:
room.sendEvent("message", "Hello, Room!");
或者,我們可以取得房間裡所有客戶的列表,然後單獨處理他們:
Collection<SocketIDClient> clients = room.getClients();
這將返回請求時房間內的所有客戶端。此清單可能會過期,因此我們應確保僅在需要時才檢索它。
7.演示
現在我們已經了解如何編寫我們的 Socket.IO 服務,讓我們看看它的實際運作情況。
我們可以編寫一個完整的客戶端應用程式如下:
Configuration config = new Configuration();
config.setHostname("localhost");
config.setPort(8081);
SocketIOServer server = new SocketIOServer(config);
server.addConnectListener(client -> {
client.joinRoom("testroom");
server.getRoomOperations("testroom")
.sendEvent("message", "Hello from " + client.getRemoteAddress());
});
server.addEventListener("message",String.class, (client, message, request) -> {
server.getRoomOperations("testroom")
.sendEvent("message", "Message from " + client.getRemoteAddress() + ": " + message);
});
server.start();
GitHub上有一個範例 HTML 檔案。在 Web 瀏覽器中開啟此文件,我們會看到一個簡單的 Socket.IO 用戶端應用程式。如果我們將其指向我們的應用程序,就能立即看到雙向傳遞的各種事件:
這個小程式就是我們建立一個小型聊天室應用程式所需的全部內容。每當有新客戶端連線或有訊息發送時,它都會向所有客戶端廣播。
8. 結論
本文簡要介紹了 Netty-socketio 及其功能。使用這個框架還可以實現更多功能,所以下次您需要運行 Socket.IO 伺服器時,不妨了解一下。
與往常一樣,本文中的所有範例都可以在 GitHub 上找到。