在本文中,我们将了解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
这将返回请求时房间中的所有客户端。这个列表可能会过时,所以我们应该确保只在需要的时候才检索它。
示范
现在我们已经了解了如何编写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客户端应用程序。
这个小应用程序就是我们构建一个小聊天室应用程序所需要的全部。每当有新客户端连接时,以及当发送任何消息时,此消息都会广播到所有客户端。