豆汁拌咖啡 2021-10-03 22:13 采纳率: 100%
浏览 91
已结题

请问用java和tomcat开发WebSocket应用,Java中其它类如何通过特定的WebSocket类向特定Session的网页用户发送消息?

我现在在用java8和Tomcat9开发一个WebSocket通讯应用。假设我的服务器端java程序已经有了A、B和C三个class。现在我希望通过一个专门的WebSocket类的class来和网页的用户进行通讯。接收信息当然是没有问题的,用WebSocket类的@OnMessage()函数就可以了。但是如何让A、B和C类能够通过WebSocket类向网页的客户端发送信息呢?因为WebSocket类是Tomcat在接收到网页的信息后通过@ServerEndpoint和@OnMessage等直接调用的,在我自己的服务器端java程序中并没有实例化WebSocket类的对象。所以我在A、B和C等其它类中无法直接调用WebSocket类向网页特定Session的用户发送信息。所以我想请教各位,如何让其它类都通过WebSocket类这一个类来向网页特定Session的用户发送信息。是把Session对象传给ABC这三个类吗?还是其它什么方法?不要告诉我ABC这三个类每个都要建立一个@ServerEndpoint啊,感觉那样太Low了,而且以后也不方便扩展。
我的服务器端java程序大体如下:

class A {
  //希望通过WebSocket类向特定Session的网页用户发送信息。
}
class B {
  //希望通过WebSocket类向特定Session的网页用户发送信息。
}
class C {
  //希望通过WebSocket类向特定Session的网页用户发送信息。
}
class WebSocket {
  @ServerEndpoint(value = "/ws/WebSocket")
  ......
  @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        connections.add(this);
    }
  @OnMessage
  public void onMessage(String message,Session session) {
  //从网页用户端接收特定Session的信息。此处没问题。
  }
  public void sendMessage(String message) {
  //如何让ABC三个类通过调用本函数向特定Session的网页用户发送消息?这里正是问题所在。望回答。
  this.session.getBasicRemote().sendText(message)
  }
}
  • 写回答

1条回答 默认 最新

  • stacksoverflow 2021-10-03 22:58
    关注

    做一个WebSocketMananger单例,
    客户端打开websocket连接后,保存客户端的sid和session到WebSocketMananger。
    其他的类想发送消息的时候,指定sid和要发送的消息,由WebSocketMananger来发送即可。

    
    class A {
      //希望通过WebSocket类向特定Session的网页用户发送信息。
        public void sendMessage(String sid, String message) {
            // 向指定的sid发送消息
            WebSocketManager.getInstance().sendMessage(sid, message);
        }
    }
    class B {
      //希望通过WebSocket类向特定Session的网页用户发送信息。
        public void sendMessage(String sid, String message) {
            // 向指定的sid发送消息
            WebSocketManager.getInstance().sendMessage(sid, message);
        }
    }
    class C {
      //希望通过WebSocket类向特定Session的网页用户发送信息。
        public void sendMessage(String sid, String message) {
            // 向指定的sid发送消息
            WebSocketManager.getInstance().sendMessage(sid, message);
        }
    }
    

    WebSocketServer.java

    
    @ServerEndpoint("/ws/WebSocket/{sid}")
    @Component
    public class WebSocketServer {
    
        @OnOpen
        public void onOpen(Session session, @PathParam("sid") String sid) {
            //客户端启动后,保存sid
            WebSocketManager.getInstance().saveSession(sid, session);
        }
    
        @OnClose
        public void onClose() {
        }
    
        @OnMessage
        public void onMessage(String message, Session session) {
            
        }
    
        @OnError
        public void onError(Session session, Throwable error) {
        }
    
    }
    

    WebSocketManager.java

    public class WebSocketManager {
    
        private static WebSocketManager instance = new WebSocketManager();
    
        private Map<String, Session> sessionMap = new HashMap<String, Session>();
    
        private WebSocketManager() {
    
        }
    
        public static WebSocketManager getInstance() {
            return instance;
        }
    
        public void saveSession(String sid, Session session) {
            sessionMap.put(sid, session);
        }
    
        public void removeSession(String sid) {
            sessionMap.remove(sid);
        }
    
        public void sendMessage(String sid, String message) {
            Session session = sessionMap.get(sid);
            if (session != null) {
                if (session.isOpen()) {
                    try {
                        session.getBasicRemote().sendText(message);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else {
                    removeSession(sid);
                }
            }
        }
    
        public boolean isOpen(String sid) {
            Session session = sessionMap.get(sid);
            return session != null && session.isOpen();
        }
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 10月12日
  • 已采纳回答 10月4日
  • 创建了问题 10月3日

悬赏问题

  • ¥15 三菱伺服电机按启动按钮有使能但不动作
  • ¥20 为什么我写出来的绘图程序是这样的,有没有lao哥改一下
  • ¥15 js,页面2返回页面1时定位进入的设备
  • ¥200 关于#c++#的问题,请各位专家解答!网站的邀请码
  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号