查看 GitHub 示例后更新:
你如何使用Guice就好了。由于MessageInbound只有一种特定的用法,因此任何像 AbstractGuiceWebSocketServlet 这样的糖都是不必要的。提供程序 chatLogHdlr 然后进行手动构造是可以的。但是您失去了AOP支持。如果需要,您可能需要进行辅助注射。但就目前而言,这很好。
另外,使用建筑注射而不是设置器注射。
我立即看到了问题所在。这不是 Guice,而是你如何使用 Guice-Persist。我没有经常使用GP,但仍然使用古老的Warp-persist。但是我看到你在代码中使用 Guice-persist 的方式存在 2 个问题:
-
您需要注入 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(每个事务的会话)使用 txn 是要走的路。
题外话:
您打算支持多少用户?如果这将是一个铁杆聊天服务器,我会使用Netty代替,但它有点复杂。谷歌搜索发现这个:
http://comoyo.github.com/blog/2012/07/30/integrating-websockets-in-netty/
原答:
所以这是一个关于风格的问题?
WebSockets != Servlets.如果他们需要稍微不同的风格,那就没有错。我甚至更愿意被提醒我不是在处理香草服务。
一些观察结果:
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(),因为它会阻碍测试。
只要继续改进风格,直到你满意为止。说如果你需要更多的帮助(会修改答案)。