当前解决方案
我有一个Java服务器(Tomcat(设置问题,我希望有人能提供一些指导。目前,我的web应用程序是一个在Tomcat 8.5上运行Java后端的单一服务器。为了处理Websocket连接,我保留了onOpen()
方法中传递的所有javax.websocket.Session
的Map
。
@ServerEndpoint("/status")
public class StatusMessenger
{
private static ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap();
@OnOpen
public void onOpen(Session session) throws Exception
{
String sessionId = session.getRequestParameterMap().get("sessionId").get(0);
sessions.put(session.getId(), session);
}
我的应用程序只向所有用户广播消息,所以我的代码中的broadcast()
只是通过sessions.values()
循环并通过每个javax.websocket.Session
发送消息。
public static void broadcast(String event, String message)
{
for (Session session: sessions.values())
{
// send the message
}
}
- 我甚至不确定这是在Tomcat中处理Websockets的正确方法,但它已经为我工作了多年,所以我认为它是可以接受的
问题
我现在想将我在AWS上的应用程序横向扩展到多个服务器。在大多数情况下,我的应用程序是无状态的,我将常规HTTP会话信息存储在数据库中。我的问题是javax.websocket.Session
的这个静态Map
——它不是无状态的,每个服务器上都有一个不同的Map
,每个服务器都有自己的javax.websocket.Session
s列表。
在我的应用程序中,在某些情况下,服务器代码需要向所有用户广播一条消息。这些事件可能发生在此多服务器设置中的任何服务器上。该事件将触发在javax.websocket.Session
s中循环的broadcast()
方法。但是,它将只在自己的Map
中的会话中循环。
如何让多服务器应用程序将此消息广播到设置中所有服务器上存储的所有websocket连接?应用程序在单个服务器上运行良好(显然(,因为只有一个websocket会话列表。换句话说,我该如何编写一个需要存储websocket连接的无状态应用程序,以便以后与它们通信?
我找到了两种替代解决方案。。。
-
在我的负载均衡器中,我制定了一条规则,将所有带有/{我的websocket服务器路径}的路径路由到1台服务器,以便所有会话都在同一台服务器上。
-
使用类似Pusher的第三方网络推送库(http://pusher.com)