Spring websocket从多个线程发送消息

时间:2018-02-04 11:57:10

标签: java spring multithreading spring-websocket

我正在为我的一个基于Spring的项目使用Spring WebSocket服务器实现。我遇到了The remote endpoint was in state [TEXT_PARTIAL_WRITING] which is invalid state的错误。我发现问题是同时从不同的线程写入websocket。

我如何暂时修复它:考虑我已经实现了以下方法

void sendMessageToSession(WebsocketSession session,String message);

将TextMessage发送到websocket会话。我无法使整个方法同步,因为多个线程可以为不同的websocketSessions和消息调用它。我也不能把会话放在synchronized块中(尝试过但没有用)

虽然,我解决了这个问题

synchronized(session.getId()){ 
    //sending message;
}

我不再面对这个问题。但是在同步块中使用字符串似乎不是一个好习惯。 那么我还有其他解决方案吗?什么是发送异步消息的最佳方式?

PS :建立连接后我已使用ConcurrentWebSocketSessionDecorator,我正在使用更新的websocket。没有帮助。

session = new ConcurrentWebSocketSessionDecorator(session, (int) StaticConfig.MAXIMUM_WS_ASYNC_SEND_TIMEOUT, StaticConfig.MAXIMUM_WS_BINARY_BUFFER_SIZE * 2);

注意 我将我的websocet会话保存在一个映射中,其中key是session.getId,value是session本身。

与其他一些websocket实现不同,Spring websocket引用在每条消息上似乎并不相同。我通过他们的ID在地图中保存了会话,并且在每条消息上,我检查传递的websocket与我已放在地图上的websocket的相等性,这是错误的。

1 个答案:

答案 0 :(得分:3)

通过在volatile后面添加WebsocketSession关键字来保存我的会话,我解决了问题。我很高兴知道这是否也是一种不好的做法。但我的想法是,当从多个线程写入websocket会话时,它们(线程)会松开websocket的状态,因为它尚未更新,这是因为它们捕获了这个异常。

通过添加volatile,我们确保在另一个线程使用它之前已更新websocket状态,因此写入websocket的工作将按预期进行同步。

我创建了一个名为SessionData的类,它包含websocketSession和我需要的有关会话的所有其他数据。

public class SessionData {
    private volatile WebSocketSession websocketSession;
    //...other 
    // getters and setters ...
}

我使用SessionData作为地图的值(其中会话ID是键)

然后从SessionData获取websocketSession并从不同的线程写入它时,volatile帮助获得更新的websocketSession。