【问题标题】:How do I access instantiated WebSockets in Jetty 9?如何在 Jetty 9 中访问实例化的 WebSocket?
【发布时间】:2013-03-16 18:54:54
【问题描述】:

这可能很明显,但我对这种范式很陌生。我创建了一个 Jetty Server 并按如下方式注册了我的 websocket 类:

        Server server = new Server(8080);
        WebSocketHandler wsHandler = new WebSocketHandler()
        {
            @Override
            public void configure(WebSocketServletFactory factory)
            {
                factory.register(MyEchoSocket.class);
            }
        };
        server.setHandler(wsHandler);

websocket 接收消息正常。我还希望能够在没有先从客户端收到消息的情况下从服务器发送消息。如何访问连接打开时创建的 MyEchoSocket 实例?或者,更一般地说,如何在 MyEchoSocket 中的 onText 方法之外的套接字上发送消息?

【问题讨论】:

  • 那不完全是服务器。从那个时候开始发送是没有意义的,因为你不知道你和谁有联系,除非你是在回应(服务)某人。
  • 我使用 WebSockets 的原因是我认为它们是您想要从服务器端推送的情况的不错选择。 MyEchoSocket 可以通过它的 onConnect() 方法来跟踪它自己的 WebSocketConnections。我只是不知道程序运行后如何访问 MyEchoSocket 的实例。
  • 你想推给谁?如果是在某人连接到您之后,那么可能会产生一些异步处理程序来进行推送。
  • 好的,有道理。基本上,每当发生某些其他事件时,我希望能够向任何与我联系的人发送消息。
  • 我不精通jetty,但我就是这样做的。当您收到请求时,您保留对套接字的引用并生成一个处理程序来执行您正在谈论的推送。请注意,在 onText 或任何服务器处理程序方法返回之后,码头不会关闭套接字。

标签: java websocket jetty


【解决方案1】:

两种常用技术,在此以超级简化的聊天室概念呈现。

选项 #1:让 WebSocket 将其状态报告回一个中心位置

@WebSocket
public class ChatSocket {
    public Session session;

    @OnWebSocketConnect
    public void onConnect(Session session) {
        this.session = session;
        ChatRoom.getInstance().join(this);
    }

    @OnWebSocketMessage
    public void onText(String message) {
        ChatRoom.getInstance().writeAllMembers("Hello all");
    }

    @OnWebSocketClose
    public void onClose(int statusCode, String reason) {
        ChatRoom.getInstance().part(this);
    }
}

public class ChatRoom {
    private static final ChatRoom INSTANCE = new ChatRoom();

    public static ChatRoom getInstance()
    {
        return INSTANCE;
    }

    private List<ChatSocket> members = new ArrayList<>();

    public void join(ChatSocket socket) 
    {
        members.add(socket);
    }

    public void part(ChatSocket socket) 
    {
        members.remove(socket);
    }

    public void writeAllMembers(String message) 
    {
        for(ChatSocket member: members)
        {
            member.session.getRemote().sendStringByFuture(message);
        }
    }

    public void writeSpecificMember(String memberName, String message) 
    {
        ChatSocket member = findMemberByName(memberName);
        member.session.getRemote().sendStringByFuture(message);
    }

    public ChatSocket findMemberByName(String memberName) 
    {
        // left as exercise to reader
    }
}

然后只需使用中心位置与您选择的 websocket 通信。

ChatRoom.getInstance().writeSpecificMember("alex", "Hello");

// or

ChatRoom.getInstance().writeAllMembers("Hello all");

选项 #2:使用 WebSocketCreator 手动创建 WebSocket

@WebSocket
public class ChatSocket {
    public ChatRoom chatroom;

    public ChatSocket(ChatRoom chatroom)
    {
        this.chatroom = chatroom;
    }

    @OnWebSocketConnect
    public void onConnect(Session session) {
        chatroom.join(this);
    }

    @OnWebSocketMessage
    public void onText(String message) {
        chatroom.writeAllMembers(message);
    }

    @OnWebSocketClose
    public void onClose(int statusCode, String reason) {
        chatroom.part(this);
    }
}

public class ChatCreator implements WebSocketCreator
{
    private ChatRoom chatroom;

    public ChatCreator(ChatRoom chatroom)
    {
        this.chatroom = chatroom;
    }

    public Object createWebSocket(UpgradeRequest request, 
                                  UpgradeResponse response)
    {
        // We want to create the Chat Socket and associate
        // it with our chatroom implementation
        return new ChatSocket(chatroom);
    }
}

public class ChatHandler extends WebSocketHandler
{
    private ChatRoom chatroom = new ChatRoom();

    @Override
    public void configure(WebSocketServletFactory factory)
    {
        factory.setCreator(new ChatCreator(chatroom));
    }
}

此时,您可以使用与上述相同的技术与您选择的 websocket 通信。

【讨论】:

  • 再一次在码头战场上拯救我。非常感谢!
  • 你不应该在这里使用private List&lt;ChatSocket&gt; members = Collections.synchronizedList(new ArrayList&lt;&gt;());吗?
  • 总是需要优化/改进。这些示例只是基础知识,以便理解技术,不作为完整/功能/优化代码给出。
  • 非常有用。非常感谢
猜你喜欢
  • 2015-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-16
  • 2017-10-07
  • 2020-08-25
  • 2019-09-27
  • 1970-01-01
相关资源
最近更新 更多