从jetty中的其他线程广播websocket消息

时间:2017-04-26 13:14:47

标签: java multithreading websocket jetty

我正在创建一个类似聊天的服务。

当用户打开页面时,他会连接到websocket端点并等待一些传入消息。

在服务器端,使用jetty的Java应用程序正在等待连接。每当用户发送消息时,它都会将消息广播给所有客户端。还有一些系统消息不时从单独的线程发送。

问题是我真的关心这个解决方案的线程安全性。根据我的理解,jetty使用带有x个工作线程的线程池,因此多个线程可以处理多个连接。我的系统消息服务也将在另一个线程上运行,甚至在jetty线程池之外。

广播功能很可能看起来像这样(通用功能名称):

for(Connection connection : server.getWebSocketConnections())
    connection.sendMessage(message);

取决于哪个线程调用它:

    在迭代期间,可能会更改由getWebSocketConnections返回的
  1. 集合。
  2. 执行sendMessage时,
  3. 连接可能已经关闭/删除/处理
  4. 可能存在一些内部缓冲竞争条件等
  5. 所以问题是:

    如何使用jetty从外部线程安全地向所有打开的websocket连接广播消息?

1 个答案:

答案 0 :(得分:1)

有趣的是,过去几周我一直在做同样的事情。 正如你所说,你需要广播是线程安全的。 我就是这样做的:

public void broadcast(String message, AnnotatedSocket excludedClient) {
    logger.debug("Sending to all clients:{} ", message);
    synchronized (clients) { 
        for (AnnotatedSocket as : clients) {
            if (!as.equals(excludedClient) && as.getSession().isOpen()) {
                try {
                    as.getSession().getRemote().sendStringByFuture(message);
                } catch (Exception e) {
                    logger.error("Error{} when broadcasting to {} {} ",e,as.getId(),as.getAddress());                                       
                }
            }
        }
    }
}

客户端是服务器拥有的同步列表,每当需要广播时,它都被所有套接字使用,但它保持线程安全,这是我所理解的。 它确实有效,但可能有更好的方法,因为我对此很陌生。 如果您感兴趣,我也实施了多播。 如果您需要有关我如何进行的更多信息,请告诉我。

干杯。