我正在开发我的第一个WebSocket应用程序,当这样的代码不能始终如一地工作时,我感到很惊讶:
@ServerEndpoint(value="/msg/{owner}", encoders=MessageEncoder.class, decoders=MessageEncoder.class)
public class WebSocketListener {
public WebSocketListener() {
}
@OnOpen
public void open(Session session, @PathParam("owner") String owner) {
if (session.getUserPrincipal() != null) {
session.getUserProperties().put("owner", owner);
}
else {
try {
session.close(new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "Not authorized"));
} catch (IOException e) {
}
}
}
@OnClose
public void close(Session session) {
}
@OnError
public void onError(Throwable error) {
}
@OnMessage
public void onMessage(final Session session, final Message message) {
String owner = (String)session.getUserProperties().get("owner");
for (Session s:session.getOpenSessions() {
System.out.println(s);
if (s.isOpen() && owner.equals(s.getUserProperties().get("owner"))) {
s.getAsyncRemote().sendObject(message);
}
}
}
}
从两个客户端和同一个“所有者”连接到此终点时,我观察到的是,有时两个会话都是从getOpenSession()返回的,但通常不仅返回该用户的会话,如的System.out.println。我的解决方法是通过向此类添加静态映射来使用getOpenSessions,使用所有者作为键将会话添加到列表中,而只是使用它。但这是一个已知的错误,我找不到任何人抱怨这个搜索?
答案 0 :(得分:0)
它似乎是tomcat中的一个bug,我在Spring Boot中遇到了与嵌入式tomcat相同的问题,将服务器更改为Jetty解决了这个问题。在Spring Docs中,有一节介绍如何切换服务器:http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-use-jetty-instead-of-tomcat