Tôi đang sử dụng tomcat 8.0.15, mùa xuân 4.1.5.WebSocket Điểm cuối từ xa đã ở trạng thái [TEXT_PARTIAL_WRITING]
Tôi đã triển khai 3 chức năng bắt buộc để sử dụng websocket như dưới đây. Rất đơn giản.
private Map<String, WebSocketSession> map_users = new ConcurrentHashMap<>();
private Map<String, String> map_id = new ConcurrentHashMap<>();
public void afterConnectionEstablished(WebSocketSession wss) throws Exception {
map_users.put(wss.getId(), wss);
}
public void afterConnectionClosed(WebSocketSession wss, CloseStatus cs) throws Exception {
map_users.remove(wss.getId());
// remove user
String username = map_id.get(wss.getId());
if (username != null) {
map_id.remove(wss.getId());
map_id.remove(username);
}
}
public void handleTextMessage(WebSocketSession wss, TextMessage tm) throws Exception {
String str = tm.getPayload();
String username = ...;
// regist user
if (!map_id.get(wss.getId())) {
map_id.put(wss.getId(), username);
map_id.put(username, wss.getId());
}
for (WebSocketSession w: map_users.values()) {
w.sendMessage(new TextMessage(wss.getId() + " send to " + w.getId() + ", msg:" + tm.getPayload()));
}
}
Một số khách hàng gửi tin nhắn và các khách hàng khác nhận được tin nhắn bằng handleTextMessage.
Trong trường hợp của tôi, không có hàm handleTextMessage, chương trình máy chủ muốn gửi tin nhắn văn bản tới khách hàng. (cho điều này tôi đã lưu của WebSocketSession Id và tên người dùng vào map_id)
String websocketsesssion_id = map_id.get(username);
WebSocketSession wss = map_users.get(websocketsesssion_id);
wss.sendMessage(new TextMessage(new java.util.Date()));
Trên đang hoạt động rất tốt. Nhưng khi một số WebSocketSession của khách hàng được sử dụng và cố gắng sử dụng đồng thời, nó sẽ gây ra lỗi. Nó có nghĩa là 1. một số khách hàng gửi tin nhắn -> handleTextMessage được gọi là -> WebSocketSession của khách hàng đang sử dụng 2. chương trình máy chủ muốn gửi tin nhắn cho khách hàng đó -> lấy WebSocketSession của khách hàng từ bản đồ -> cố gắng gửi tin nhắn với cùng WebSocketSession
Stacktrace:] with root cause
java.lang.IllegalStateException: The remote endpoint was in state [TEXT_PARTIAL_WRITING] which is an invalid state for called method
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.checkState(WsRemoteEndpointImplBase.java:1092)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.textPartialStart(WsRemoteEndpointImplBase.java:1050)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendPartialString(WsRemoteEndpointImplBase.java:218)
at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendText(WsRemoteEndpointBasic.java:49)
at org.springframework.web.socket.adapter.standard.StandardWebSocketSession.sendTextMessage(StandardWebSocketSession.java:197)
at org.springframework.web.socket.adapter.AbstractWebSocketSession.sendMessage(AbstractWebSocketSession.java:105)
at org.springframework.web.socket.sockjs.transport.session.WebSocketServerSockJsSession.writeFrameInternal(WebSocketServerSockJsSession.java:222)
at org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession.writeFrame(AbstractSockJsSession.java:325)
at org.springframework.web.socket.sockjs.transport.session.WebSocketServerSockJsSession.sendMessageInternal(WebSocketServerSockJsSession.java:212)
at org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession.sendMessage(AbstractSockJsSession.java:161)
Kết quả là WebSocketSession bị đóng và khách hàng phải mở lại WebSocketSession mới.
Vì vậy, câu hỏi của tôi là:
Tôi có thể kiểm tra xem WebSocketSession có đang được sử dụng hay không? (ngoài chức năng handleTextMessage)