我开始将我现有的Jetty9应用程序webapp迁移到Spring Boot上,但我似乎不知道如何使用Jetty WebSocketHandler,而不是Spring WebSocketHandler和WebSocketSession。
我可以在我的Application.java中正确地设置Spring WebSocketHandler,我在Spring Framework文档中找到了JettyWebSocketHandlerAdaptor和JettyWebSocketSession类,但我还没有找到如何使用它或任何好的示例。
http://docs.spring.io/autorepo/docs/spring-framework/4.1.9.RELEASE/javadoc-api/org/springframework/web/socket/adapter/jetty/JettyWebSocketHandlerAdapter.html
如何将WebSocketHandler交给Jetty?因为JettyWebSocketAdapter不是从Object派生的,所以我一直在尝试注册一个Spring WebSocketHandler,然后让它的所有方法都传递给一个JettyWebSocketHandler。我这么做是不是太傻了:
Application.java
@EnableWebSocket
@SpringBootApplication
public class Application extends SpringBootServletInitializer implements WebSocketConfigurer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
SpringWSHandler springPlease = new SpringWSHandler();
registry.addHandler(springPlease, "/websocket").setHandshakeHandler(handshaker());
}
@Bean
public DefaultHandshakeHandler handshaker()
{
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
policy.setInputBufferSize(8192);
policy.setIdleTimeout(600000);
return new DefaultHandshakeHandler(new JettyRequestUpgradeStrategy(new WebSocketServerFactory(policy)));
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}Spring WebSocketHandler
@Component
public class SpringWSHandler implements WebSocketHandler {
private JettyHandler jettyHandler;
private JettyWebSocketSession jettySession;
private static Logger logger = LoggerFactory.getLogger(SpringWSHandler.class);
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
logger.debug("Connection Established: " + session.getId());
jettySession = new JettyWebSocketSession(session.getAttributes());
jettyHandler = new JettyHandler(this, jettySession);
jettyHandler.onOpen(jettySession.getNativeSession());
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
logger.debug("Message from session: " + session.getId());
jettyHandler.onMessage(message.getPayload().toString());
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
//TODO
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
logger.debug("Closing the session: " + session.getId());
jettyHandler.onClose(closeStatus.getCode(), "Closing Connection");
session.close(closeStatus);
}
@Override
public boolean supportsPartialMessages() {
return true;
}
}它失败了,因为在我打开我的网页后,每当我试图使用它时,网页套接字连接似乎都会关闭。一旦我尝试使用jettyHandler的方法,连接就会关闭,异常是一个ExceptionWebSocketHandlerDecorator异常:
11:44:27.530 [qtp1014565006-19] ERROR o.s.w.s.h.ExceptionWebSocketHandlerDecorator - Unhandled error for ExceptionWebSocketHandlerDecorator [delegate=LoggingWebSocketHandlerDecorator [delegate=org.appcad.webserver.jetty.SpringWSHandler@5a7b309b]]
java.lang.NullPointerException: null发布于 2016-08-05 01:58:58
直接使用Spring的WebSocketHandler或Jetty的WebSocketHandler,不要尝试将它们混合在一起。
您不能以这种方式使用Jetty WebSocketHandler,因为它需要是Jetty LifeCycle层次结构的一部分,并且能够正常访问Jetty Server。
让一个合适的Jetty访问Spring层也是很困难的,因为Jetty和WebSocketHandler之间的LifeCycle不会像那样融合在一起。
也许您可以使用WebSocketUpgradeFilter和WebSocketCreator的自定义实现来初始化您的目标WebSocket,并在完成后访问Spring层。
您的自定义WebSocketCreator将在每次发生新的传入websocket升级时被调用。
发布于 2016-08-05 04:12:59
我已经设法破解了一些暂时有效的东西,但我希望听到一个更好、更合适的方法来使用Jetty WebSockets和Spring Boot。
这允许我将消息从Spring传递到我的JettyWebSocketHandlerAdapter (JettyHandler)类,后者将消息传递给我的WebSocket WebSocket和相关的类。
Application.java中的WebSocketHandler设置
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
SpringWSHandler springPlease = new SpringWSHandler();
registry.addHandler(springPlease, "/websocket").setHandshakeHandler(factoryBean());
}
//Configure buffer size and timeouts
@Bean
public HandshakeHandler factoryBean()
{
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
policy.setInputBufferSize(8192);
policy.setIdleTimeout(3600000);
WebSocketServerFactory factory = new WebSocketServerFactory(policy);
return new DefaultHandshakeHandler(new JettyRequestUpgradeStrategy(factory));
}SpringWSHandler.java
@Component
public class SpringWSHandler implements WebSocketHandler {
private JettyHandler jettyHandler;
private JettyWebSocketSession jettySession;
private static Logger logger = LoggerFactory.getLogger(SpringWSHandler.class);
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
//Application.java adapts WebSocket connections to Jetty 9 API when registering handlers with the Jetty handshaker
//We can cast spring WebSocketSessions to JettyWebSocketSessions, and initialize the org.eclipse.jetty.websocket.api.Session with itself.
jettySession = (JettyWebSocketSession) session;
jettySession.initializeNativeSession(jettySession.getNativeSession());
//Setup our custom handler and populate the router, which was magically created by Spring using our annotated classes in Router and its dependencies.
jettyHandler = new ClothoJettyHandler(this, jettySession);
//Let the jetty web socket commence!
jettyHandler.onOpen(jettySession.getNativeSession());
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
logger.debug("Message from session: " + session.getId());
jettyHandler.onMessage(message.getPayload().toString());
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
//TODO
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
logger.debug("Closing the session: " + session.getId());
jettyHandler.onClose(closeStatus.getCode(), "Closing Connection");
session.close(closeStatus);
}
@Override
public boolean supportsPartialMessages() {
return true;
}
}https://stackoverflow.com/questions/38771666
复制相似问题