- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我有一个需要使用 Tomcat 7 网络套接字的 webapp。
在这个 web 应用程序中,所有标准 Servlet(那些扩展 javax.servlet.http.HttpServlet
)都可以很好地(并且正确地)与 Google Guice 一起工作。为了让我的 Servlet 与 Guice 处理程序一起工作,我只是:
@Singleton
MyHandler
实例声明私有(private) Provider
并生成一个标记为注入(inject)的 setter @Inject
举例说明以上几点:
@Singleton
public class MyServlet extends HttpServlet {
private Provider<MyHandler> myHandler;
@Inject
MyServlet() {
}
@Override
protected void service(..) throws ServletException { ... }
@Inject
public void setMyHandler(Provider<MyHandler> myHandler) {
this.myHandler = myHandler;
}
...
}
如何从 WebSocketServlet
调用上面称为 myHandler
的同一个 Guice 处理程序?
我不能采用与标准 servlet 用例相同的样式,因为每个 WebSocket 通信都会产生一个扩展 MessageInbound
的实例,而不是像标准 servlet 那样具有单例 servlet。 ;然后从 MessageInbound 实例中的方法(例如 onOpen
或 onClose
)调用将调用 MyHandler
的适当方法; 不是来自 HttpServlet
实例中的方法,如上面的 MyServlet
。
我尝试了什么?我确实尝试了一些(概念上错误的)解决方案,例如从 MessageInbound
实例中调用 websocket-servlet 的处理程序;这当然会导致降低 Guice 堆栈跟踪的范围问题。这样做的概念正确方法是什么?
最佳答案
查看 GitHub 示例后更新:
您使用 Guice 的方式很好。由于 MessageInbound 只有一种特殊用法,因此不需要像 AbstractGuiceWebSocketServlet 这样的糖。提供者 chatLogHdlr 再做手动构建就可以了。但是你失去了 AOP 支持。如果需要,您可能需要进行辅助注入(inject)。但现在这很好。
附带说明,使用构造注入(inject)而不是 setter 注入(inject)。
我立即看到了问题所在。 这不是 Guice,而是你如何使用 Guice-Persist。 我没有经常使用 GP,仍然使用古老的 Warp-persist。但我发现您在代码中使用 Guice-persist 的方式存在 2 个问题:
你需要注入(inject) PersistService 来启动 Guice-Persist。在 WIKI 中有解释。例如
public class PocWebApp extends GuiceServletContextListener {
@Inject
PersistService ps;
@Override
protected Injector getInjector() {
Injector injector = Guice.createInjector(new ServletModule() {
@Override
protected void configureServlets() {
install(new JpaPersistModule("DesktopPU"));
serve("/socket/main/").with(MainSocket.class);
}
});
injector.injectMembers(this);
return injector;
}
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
super.contextInitialized(servletContextEvent);
ps.start();
}
}
PersistFilter 没用,因为只有第一次 WebSocket 会通过过滤器,但所有后续通信都不会通过过滤器。在@Transactional (Session-per-transaction) 附近使用 txn 是可行的方法。
题外话:
您打算支持多少用户?如果这将是一个核心聊天服务器,我会改用 Netty,但它会涉及更多。谷歌搜索发现:
http://comoyo.github.com/blog/2012/07/30/integrating-websockets-in-netty/
原答案:
所以这是一个关于风格的问题?
WebSockets != Servlets。 如果它们需要稍微不同的样式,那也没有错。我什至更愿意被提醒我不是在处理 vanilla servlet。
一些观察:
WebSocketServlet没什么特别的。您可以轻松地将它与 Guice-Servlet 一起使用。例如:
@Singleton
public class FooGuiceWebSocketServlet extends WebSocketServlet {...}
然后将其称为
serve("/foo").with(FooGuiceWebSocketServlet.class);
现在,MessageInbound正如您所解释的,这很特别,因为所有这些都由 Tomcat 处理。 MessageInbound 是 WebSocket 范围的。现在 Guice 对这个范围一无所知,因此保留它可能是有意义的。
对于初学者,我会确保 MessageInbound 是由 Guice 创建的。类似这样的事情:
@Singleton
public class ExampleWebSocketServlet extends AbstractGuiceWebSocketServlet {
@Override
public Class<? extends StreamInbound> serveWith() {
return Foo.class;
}
public static class Foo extends MessageInbound {
@Inject GuiceCreatedAndInjected bar;
@Override
protected void onBinaryMessage(ByteBuffer byteBuffer) throws IOException {
// do nothing
}
@Override
protected void onTextMessage(CharBuffer charBuffer) throws IOException {
// this getSwOutbonds() is not very friendly to testing
getWsOutbound().writeTextMessage(bar.echo(charBuffer));
}
}
}
在哪里
public abstract class AbstractGuiceWebSocketServlet extends WebSocketServlet {
@Inject Injector injector;
@Override
protected StreamInbound createWebSocketInbound(String subProtocol, HttpServletRequest request) {
return injector.getInstance(serveWith());
}
public abstract Class<? extends StreamInbound> serveWith();
}
您可以根据需要从这里转到更高的抽象和/或范围。我不是特别喜欢#getWsOutbound()因为它会妨碍测试。
不断改进风格,直到您满意为止。说你是否需要更多帮助(将修改答案)。
关于java - Tomcat WebSocketServlet 和 Google Guice,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13958143/
我正在使用 Jetty 9 设置 WebSocket 处理程序。我见过使用 WebSocketHandler 或 WebSocketServlet 的示例。 这就是我正在做的事情: public cl
我正在尝试在我正在处理的嵌入式 Jetty 应用程序中测试 WebSocket 支持。我的目标是将数据从服务器流式传输到浏览器。我还没有解决所有问题,因为我刚刚开始设置 WebSocket servl
我正在尝试采用使用(现已弃用)WebSocketServlet 的旧代码。旧代码如下所示: @Singleton ExampleServlet extends WebSocketServlet {
我有一个需要使用 Tomcat 7 网络套接字的 webapp。 在这个 web 应用程序中,所有标准 Servlet(那些扩展 javax.servlet.http.HttpServlet)都可以很
本文整理了Java中org.eclipse.jetty.websocket.WebSocketServlet.init()方法的一些代码示例,展示了WebSocketServlet.init()的具体
本文整理了Java中org.eclipse.jetty.websocket.WebSocketServlet.getInitParameter()方法的一些代码示例,展示了WebSocketServl
我见过很多关于如何为 HTTPS 配置 Jetty 的示例 SSL for Jetty但它们似乎都利用一个单独的 Server 类,其中包含一个 main 方法来执行。我想将我的 WebServlet
我正在尝试访问 HttpServlet 中设置的 session 属性来自 WebSocketServlet 我有两个 ServletContextHandler对象,都带有 SESSIONS启用:
我是一名优秀的程序员,十分优秀!