我正在开发我的第一个 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);
}
}
}
}
当从两个客户端和同一个“所有者”连接到此端点时,我观察到有时两个 session 都从 getOpenSession() 返回,但更多时候不仅返回该用户的 session ,如系统.out.println。我的解决方法是通过向此类添加静态映射来放弃使用 getOpenSessions,将 session 添加到使用所有者作为键的列表中,然后只使用它。但这是一个已知的错误吗,我在搜索中找不到任何人提示这个?
最佳答案
这似乎是 tomcat 中的一个错误,我在 Spring Boot 中使用嵌入式 tomcat 时遇到了同样的问题,将服务器更改为 Jetty 解决了这个问题。在 Spring Docs 中,有一节解释了如何切换服务器:http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-use-jetty-instead-of-tomcat
关于java - Tomcat 8 getOpenSessions() 没有返回端点的所有 session ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38268369/