我怎样才能有一个主要方法和 websockets
How can I have a main method and websockets
我正在寻找在网络搜索中找不到的更多信息。我很可能在寻找错误的东西,我希望有人能纠正我。
我已经实现了客户端(java脚本)-服务器(java)websocket 应用程序。我有多个客户端的连接,现在我想从 main 方法创建的一些初始数据开始。但是,我的 java 应用程序中的主要方法未链接到 websocket 端点。因此,如果我在 运行 应用程序时创建对象实例,我希望将该信息发送到会话操作闭环之外的已连接客户端。
我所描述的内容听起来不可能,但我确信我没有正确解释它。
结论:
在处理 websocket 时,我怎样才能有一个 OnServerStartup 可以这么说,以便我可以加载保存的数据或创建初始数据?
背景:
我已经使用 javax.websocket.server 实现了带注释的服务器端点。由于出现故障可能导致我困惑的历史是我首先从 java 应用程序开始,然后我想要一个客户端 UI 来添加、编辑、删除数据。所以我使用 javascript 前端通过 websockets 与我的 java 应用程序通信。现在我的应用程序无法与 websocket 连接通信,或者至少我还不知道如何。
理想情况下,我要做的是让用户操作通过 websocket 进入,然后我想将这些操作放入我的应用程序随后处理的队列中。完成后,它将对数据集产生的更改发送到所有活动会话。这里有一个大问题,因为我想在允许 websocket 连接之前初始化保存的数据。此外,如果我有一个定时事件,我希望能够将所有更新发送到连接的会话。
这是三个解决方案。他们可能不会帮助使用 Glassfish 的原始海报;我不知道。但它们是已发布问题的答案,可能会有一些用处。
我的服务器使用嵌入式 Jetty。 (这意味着服务器是在我的 Java 代码中创建的,所以我可以访问所有内容。)
答案 1: 让您的 websocket 服务器端点侦听从您的主线程发送的 CDI 事件。我没有这样做过,但我认为这是一个非常干净的概念。
答案 2: 让你的端点 "register" 本身与主线程。
在核心中创建静态集合成员class:
public class Core()
...
public static List<MyEndpoint> webSockets = new ArrayList<MyEndpoint>();
端点将自己添加到集合中:
@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 中处理从列表中删除的操作,并在迭代期间监视已关闭的套接字。
请注意,可以根据需要以其他方式完成同步: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。
并且 包含关于端点实例的长篇讨论。
我正在寻找在网络搜索中找不到的更多信息。我很可能在寻找错误的东西,我希望有人能纠正我。
我已经实现了客户端(java脚本)-服务器(java)websocket 应用程序。我有多个客户端的连接,现在我想从 main 方法创建的一些初始数据开始。但是,我的 java 应用程序中的主要方法未链接到 websocket 端点。因此,如果我在 运行 应用程序时创建对象实例,我希望将该信息发送到会话操作闭环之外的已连接客户端。
我所描述的内容听起来不可能,但我确信我没有正确解释它。
结论:
在处理 websocket 时,我怎样才能有一个 OnServerStartup 可以这么说,以便我可以加载保存的数据或创建初始数据?
背景:
我已经使用 javax.websocket.server 实现了带注释的服务器端点。由于出现故障可能导致我困惑的历史是我首先从 java 应用程序开始,然后我想要一个客户端 UI 来添加、编辑、删除数据。所以我使用 javascript 前端通过 websockets 与我的 java 应用程序通信。现在我的应用程序无法与 websocket 连接通信,或者至少我还不知道如何。
理想情况下,我要做的是让用户操作通过 websocket 进入,然后我想将这些操作放入我的应用程序随后处理的队列中。完成后,它将对数据集产生的更改发送到所有活动会话。这里有一个大问题,因为我想在允许 websocket 连接之前初始化保存的数据。此外,如果我有一个定时事件,我希望能够将所有更新发送到连接的会话。
这是三个解决方案。他们可能不会帮助使用 Glassfish 的原始海报;我不知道。但它们是已发布问题的答案,可能会有一些用处。
我的服务器使用嵌入式 Jetty。 (这意味着服务器是在我的 Java 代码中创建的,所以我可以访问所有内容。)
答案 1: 让您的 websocket 服务器端点侦听从您的主线程发送的 CDI 事件。我没有这样做过,但我认为这是一个非常干净的概念。
答案 2: 让你的端点 "register" 本身与主线程。
在核心中创建静态集合成员class:
public class Core()
...
public static List<MyEndpoint> webSockets = new ArrayList<MyEndpoint>();
端点将自己添加到集合中:
@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 中处理从列表中删除的操作,并在迭代期间监视已关闭的套接字。
请注意,可以根据需要以其他方式完成同步: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。
并且 包含关于端点实例的长篇讨论。