मैं टॉमकैट 8.0.15, वसंत 4.1.5 का उपयोग कर रहा हूं।वेबसॉकेट रिमोट एंडपॉइंट राज्य में था [TEXT_PARTIAL_WRITING]
मैंने नीचे की तरह websocket का उपयोग करने के लिए 3 अनिवार्य कार्यों को लागू किया। यह बहुत आसान है।
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()));
}
}
कुछ ग्राहक संदेश भेजते हैं और अन्य क्लाइंट हैंडलटेक्स्ट मैसेज द्वारा संदेश प्राप्त करते हैं।
मेरे मामले में, हैंडलटेक्स्ट मैसेज फ़ंक्शन के बिना, सर्वर प्रोग्राम क्लाइंट को एक टेक्स्ट संदेश भेजना चाहता है।
String websocketsesssion_id = map_id.get(username);
WebSocketSession wss = map_users.get(websocketsesssion_id);
wss.sendMessage(new TextMessage(new java.util.Date()));
कोड से ऊपर बहुत अच्छी तरह से काम करता है (इस के लिए मैं एक WebSocketSession की ईद और map_id में उपयोगकर्ता नाम बचाया)। लेकिन जब कुछ क्लाइंट का वेबसाकेट सत्र उपयोग में है और एक साथ उपयोग करने का प्रयास करता है, तो यह त्रुटि बनाता है। इसका मतलब है 1. कुछ क्लाइंट संदेश भेजते हैं -> हैंडलटेक्स्ट मैसेज को -> क्लाइंट का वेबसाकेट सत्र का उपयोग कर रहा है 2. सर्वर प्रोग्राम उस क्लाइंट को संदेश भेजना चाहता है -> क्लाइंट के वेबसाकेट सत्र को मानचित्र से प्राप्त करें -> कोशिश करें एक ही 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)
परिणाम के रूप में साथ संदेश भेजते हैं, WebSocketSession बंद कर दिया है और ग्राहक फिर से नया WebSocketSession खोलने के लिए है।
तो, मेरे सवाल यह है:
मैं जांच कर सकता है कि क्या WebSocketSession उपयोग में है या नहीं? (handleTextMessage समारोह के बाहर)