我正在为我的一个基于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的相等性,这是错误的。
答案 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。