我怎样才能有一个主方法和websockets

时间:2015-11-28 19:21:39

标签: java java-websocket

我正在寻找在搜索网络时找不到的更多信息。我很可能正在寻找错误的东西,我希望有人可以纠正我。

我已经实现了一个客户端(javascript)-server(java)websocket应用程序。我有连接为几个客户端工作,现在我想从一个主方法创建的一些初始数据开始。但是,我在java应用程序中使用的主要方法没有链接到websocket端点。因此,如果我在运行应用程序时创建对象实例,我希望将这些信息发送到闭合的会话操作循环之外的连接客户端。

我所描述的听起来不可能,但我确信我只是没有正确解释。

结论:

在处理websockets时,我怎么能有一个OnServerStartup这样说我可以加载保存的数据或创建初始数据?

背景:

我使用javax.websocket.server实现了带注释的服务器端点。由于故障导致的历史可能导致我的问题在于我首先使用java应用程序,然后我想要一个客户端UI来添加,编辑和删除数据。所以我选择了通过websockets与我的java应用程序通信的javascript前端。现在我的应用程序无法与websocket连接通信,或者至少我不知道如何。

理想情况下,我要做的是通过websocket进行使用,然后我想将操作放入我的应用程序随后处理的队列中。完成后,它会将对数据集的结果更改发送到所有活动会话。这里有一个很大的问题,因为我想在允许websocket连接之前初始化已保存的数据。此外,如果我有定时事件,我希望能够将所有更新发送到连接的会话。

1 个答案:

答案 0 :(得分:1)

以下是三种解决方案。他们可能无法帮助使用Glassfish的原始海报;我不知道。但它们是已发布问题的答案,可能会有所帮助。

我使用嵌入式Jetty作为我的服务器。 (这意味着服务器是在我的Java代码中创建的,因此我可以访问所有内容。)

答案1:让您的websocket服务器端点监听从主线程发送的CDI事件。我没有这样做,但我认为这是一个非常干净的概念。

回答2:让您的终端"注册"本身就是主线。

在核心类中创建静态集合成员:

public class Core()
...
    public static List<MyEndpoint> webSockets = new ArrayList<MyEndpoint>();

Endpoint将self添加到集合中:

@ServerEndpoint(value="/path/")
public class MyEndpoint
{
    @OnOpen
    public void onWebSocketConnect(javax.websocket.Session session)
    {
        synchronized(Core.webSockets)
        {
            Core.webSockets.add(this);
        }
        ...
    }

返回Core,您将遍历webSockets以发送消息。同步迭代,或者更好,复制webSockets并迭代复制(标准同步集合实践)。您还需要在@OnClose中处理从List中删除,并在迭代期间监视已关闭的套接字。

请注意,可能会根据需要以其他方式完成同步:Collections.synchronizedList()或CopyOnWriteArrayList在不同情况下非常有用。

回答3:控制构建端点实例。这是我最强大的选择,因为您可以使用数据和外部引用构建它。

我的实现是基于JSR-356(和Jetty),但是在其他框架中也有钩子。总是有点复杂。

在服务器创建期间:

context = new ServletContextHandler(ServletContextHandler.SESSIONS);
// ... more server creation

ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext(context);

wscontainer.addEndpoint(ServerEndpointConfig.Builder.create(MyEndpoint.class, "/path/")
    .configurator(new MyConfigurator(aSocketManagerObject))
    .build());

其中:

public class MyConfigurator extends javax.websocket.server.ServerEndpointConfig.Configurator
{
    private final ManagerObject aSocketManagerObject;

    public EventsConfigurator(ManagerObject aSocketManagerObject)
    {
        this.aSocketManagerObject = aSocketManagerObject;
    }

    @Override
    public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException
    {
        return (T) new MyEndpoint(aSocketManagerObject); // This constructor to be added to your MyEndpoint class
    }
}

端点现在具有对aSocketManagerObject的引用,并且可以自由地与其通信以获取数据,注册为侦听器,等等。

Bhaskar S.在Introduction to WebSockets

提供了答案3的强大实施

修改

有关CDI方法的更多信息有问题,How to get an existing websocket instance

Accessing HttpSession from HttpServletRequest in a Web Socket @ServerEndpoint包括对端点实例的长篇讨论。