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

请问用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();
    }
}