请问用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)
}
}
答
做一个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();
}
}