netty-socketio:实时Socket.IO的服务器端java框架


在本文中,我们将了解Netty-socketio库。我们将探讨它是什么,并了解如何使用它来构建与Web应用程序通信的Socket.IO服务。


什么是Socket.IO?
Netty-socketio概述:这个项目是一个开源的Java实现的Socket.IO服务器。基于NettyServer框架。
在Java上实现的Socket.IO服务器与实时java框架

什么是Socket.IO
IO是一个支持客户端和服务器之间低延迟、双向和基于事件的通信的库。IO是一个JavaScript库,它使应用程序能够在浏览器和后端服务器之间建立低延迟、双向、基于事件的通信。通常,这是使用WebSockets完成的,尽管Socket.IO库还支持较新的WebTransport API,或者在需要时回退到HTTP长轮询。

我们可以使用Socket.IO库来抽象底层的传输,使其更容易在代码中处理通信。然而,它所做的还不止于此。它保证按顺序传递消息,即使在不可靠的网络连接上也尽最大努力传递消息。

在服务器内部,Socket.IO自动管理连接-为每个连接分配一个唯一的ID。然后它允许我们将命名的事件发送到连接的另一端,允许接收端了解如何根据名称处理事件。

我们也可以将事件分解到房间中。这些是可以存在于我们的服务中的任意通道,允许我们轻松地一次性与整个客户端集进行通信。



设置Netty-Socketio
Netty-Socketio是一个Java库,它使用Netty网络服务器来运行一个可以处理Socket.IO连接的网络服务器。然后,我们可以将其用作Socket.IO客户端的后端来与之通信。

1.依赖关系
为了使用这个,我们需要包括最新版本在我们的大楼里,当前版本2.0.13.

如果我们使用Maven,我们可以在pom.xml文件中包含此依赖项:



    com.corundumstudio.socketio
    netty-socketio
    2.0.13

此时,我们已准备好开始在应用程序中使用它。

2.创建网络服务器
一旦我们添加了依赖项,我们需要为Socket.IO流量创建一个网络服务器。Netty-socketio通过创建一个全新的网络服务器来工作,这意味着即使我们的应用程序中没有任何其他服务器,我们也可以使用它-例如,如果我们没有运行像Tomcat这样的Web服务器的话。然而,这确实意味着如果我们在Web应用程序中使用它,那么我们需要在不同的端口上侦听。

我们需要做的第一件事是创建我们的服务器配置:


Configuration config = new Configuration();
config.setHostname("localhost");
config.setPort(8081);
这会告诉Netty-socketio运行服务器的主机和端口。

然后我们可以使用它来构造Socket IO Server的实例:

SocketIOServer server = new SocketIOServer(config);

最后,我们可以启动服务器运行:

server.start();

此时,我们的服务器可以处理Socket.IO连接。然而,我们还没有对它们做任何事情。

3.连接到我们的服务器
除了服务器之外,我们还需要一个可以连接到它的Socket.IO客户端。通常,这意味着代码在我们的Web浏览器中运行。

可以从CDN包含Socket.IO客户端库,如下所示:

然后我们可以使用它来连接到我们的服务器:

// JavaScript
const socket = io("ws://localhost:8081");

这将为我们提供一个到Socket.IO服务器的活动连接,然后我们可以使用它与后端通信。



处理事件
一旦我们的网络服务器正常工作,我们就需要能够对事件做出反应。我们通过为我们感兴趣的事件注册事件侦听器来做到这一点。

首先,我们可以注册事件侦听器,以便在新客户端连接或现有客户端断开连接时得到通知:


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);
这就允许我们为不同类型的事件注册不同的处理程序,然后让客户端适当地发送这些不同的事件。


发送消息
现在我们可以接收从客户端发送的消息,我们还需要能够将消息发送回客户端。

任何时候我们只要提到一个客户,一个合适的SocketIOClient实例-我们可以用它来发送事件到客户端。我们从哪里得到这个引用-例如,如果它是对传入事件的响应,或者因为我们之前存储了它以供以后使用-这无关紧要。唯一重要的是客户端仍然连接。

我们使用sendEvent()方法管理此操作,同时获取要发送的事件的名称和有效负载:

client.sendEvent("message", payload);

与普通的HTTP处理程序不同,不要求我们在响应传入消息时这样做。我们可以在任何时候根据我们想要的触发器向任何客户端发送消息。我们只需要一个对客户端的引用和一个活动连接。



客房
除了处理单个客户端之外,Socket.IO还有“Rooms”的概念。这是一种将多个客户端分组在一个已知的房间名称下的方法。一旦完成,我们就可以把它们作为一个整体来处理。

我们可以使用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 clients = room.getClients();

这将返回请求时房间中的所有客户端。这个列表可能会过时,所以我们应该确保只在需要的时候才检索它。



示范
现在我们已经了解了如何编写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客户端应用程序。


这个小应用程序就是我们构建一个小聊天室应用程序所需要的全部。每当有新客户端连接时,以及当发送任何消息时,此消息都会广播到所有客户端。