我正在尝试将web套接字通知添加到一个运行在Glassfish 3.1.2和Spring4.1.5版本上的旧应用程序中。实现Spring的websockets不起作用,因为它需要GlassFish 4.1+,我们不能升级应用服务器。我正在使用GrizzlyWebSocket1.9.x,我创建了一个非常基本的@Component,扩展了WebSocketApplication类并实现了与bean事件相关的接口。这是对象
@Component
public class CCMarshaller extends WebSocketApplication implements InitializingBean, DisposableBean {
private static final String TOPIC = "/realtime-channel";
@Override
public WebSocket createWebSocket(ProtocolHandler protocolHandler, WebSocketListener... listeners) {
return new DefaultWebSocket(protocolHandler, listeners);
}
@Override
public boolean isApplicationRequest(Request request) {
final String uri = request.requestURI().toString();
return uri.endsWith(TOPIC);
}
/* Test */
@Override
public void onMessage(WebSocket socket, String text) {
EventDto e = new EventDto();
e.setId(45);
broadcast(e);
}
private void broadcast(EventDto evt) {
for (WebSocket webSocket : getWebSockets()) {
if (!webSocket.isConnected()) {
continue;
}
try {
ObjectMapper mapper = new ObjectMapper();
webSocket.send(mapper.writeValueAsString(evt));
} catch (WebSocketException e) {
e.printStackTrace();
webSocket.close();
} catch (JsonProcessingException e) {
e.printStackTrace();
webSocket.close();
}
}
}
@Override
public void afterPropertiesSet() throws Exception {
WebSocketEngine.getEngine().register(this);
}
@Override
public void destroy() throws Exception {
WebSocketEngine.getEngine().unregister(this);
}
}我对Spring非常陌生,但是我对这个bean的生命周期的理解是(大约):(1)启动时的单例创建,(2)然后框架调用afterPropertiesSet,(3)注册WebSocketApplication对象( this )和(4)对/实时通道的每个请求将由调用OnMessage回调的WebSocketApplication处理。broadcast函数是一个帮助器,用于向所有连接的套接字广播一个对象(对象被转换为json)。
起作用了..。(暂时:)
当应用程序启动时,我可以登录并导航javascript连接用几行代码完成的第一个页面:
var WSManager = {
url: 'ws://' + window.location.host + '/realtime-channel',
init: function() {
websocket = new WebSocket(WSManager.url);
websocket.onmessage = function (evt) {
// process message with jquery
};
}
};
WSManager.init();客户端通过websocket连接后,应用程序可以发送消息并接收(在广播中)对象,因此它运行良好。即使我连接到其他的websocket测试工具,效果也很好。当我尝试导航到其他页面(纯Spring导航)时,问题就出现了。应用程序挂起,server.log显示以下消息:
[#|2017-11-24T13:36:32.350+0100|WARNING|glassfish3.1.2|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=139;_ThreadName=Thread-2;|StandardWrapperValve[mvc-dispatcher]: PWC1406: Servlet.service() for servlet mvc-dispatcher threw exception
java.lang.NullPointerException
at org.apache.catalina.connector.Request.setAttribute(Request.java:1688)
at org.apache.catalina.connector.RequestFacade.setAttribute(RequestFacade.java:570)
at org.springframework.web.context.request.async.WebAsyncUtils.getAsyncManager(WebAsyncUtils.java:49)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1023)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1542)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849)
at com.sun.grizzly.arp.DefaultAsyncExecutor.execute(DefaultAsyncExecutor.java:159)
at com.sun.grizzly.arp.DefaultAsyncExecutor.interrupt(DefaultAsyncExecutor.java:145)
at com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:102)
at com.sun.grizzly.http.TaskBase.run(TaskBase.java:193)
at com.sun.grizzly.http.TaskBase.execute(TaskBase.java:175)
at com.sun.grizzly.arp.DefaultAsyncHandler.handle(DefaultAsyncHandler.java:145)
at com.sun.grizzly.arp.AsyncProtocolFilter.execute(AsyncProtocolFilter.java:210)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:745)
|#]
[#|2017-11-24T13:36:32.351+0100|SEVERE|glassfish3.1.2|org.apache.catalina.connector.CoyoteAdapter|_ThreadID=139;_ThreadName=Thread-2;|PWC3989: An exception or error occurred in the container during the request processing
java.lang.NullPointerException
at org.apache.catalina.connector.Request.setAttribute(Request.java:1688)
at org.apache.catalina.connector.RequestFacade.setAttribute(RequestFacade.java:570)
at org.apache.catalina.core.StandardWrapperValve.exception(StandardWrapperValve.java:465)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:335)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849)
at com.sun.grizzly.arp.DefaultAsyncExecutor.execute(DefaultAsyncExecutor.java:159)
at com.sun.grizzly.arp.DefaultAsyncExecutor.interrupt(DefaultAsyncExecutor.java:145)
at com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:102)
at com.sun.grizzly.http.TaskBase.run(TaskBase.java:193)
at com.sun.grizzly.http.TaskBase.execute(TaskBase.java:175)
at com.sun.grizzly.arp.DefaultAsyncHandler.handle(DefaultAsyncHandler.java:145)
at com.sun.grizzly.arp.AsyncProtocolFilter.execute(AsyncProtocolFilter.java:210)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:745)
|#]
[#|2017-11-24T13:36:32.354+0100|SEVERE|glassfish3.1.2|com.sun.grizzly.config.GrizzlyServiceListener|_ThreadID=139;_ThreadName=Thread-2;|java.lang.NullPointerException
at com.sun.grizzly.arp.AsyncProcessorTask.obtainAndSetThreadAttachment(AsyncProcessorTask.java:230)
at com.sun.grizzly.arp.AsyncProcessorTask.enableTimeout(AsyncProcessorTask.java:223)
at com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:127)
at com.sun.grizzly.http.TaskBase.run(TaskBase.java:193)
at com.sun.grizzly.http.TaskBase.execute(TaskBase.java:175)
at com.sun.grizzly.arp.DefaultAsyncHandler.handle(DefaultAsyncHandler.java:145)
at com.sun.grizzly.arp.AsyncProtocolFilter.execute(AsyncProtocolFilter.java:210)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:745)
|#]
[#|2017-11-24T13:36:32.354+0100|INFO|glassfish3.1.2|com.sun.grizzly.config.GrizzlyServiceListener|_ThreadID=139;_ThreadName=Thread-2;|Processor exception
java.lang.RuntimeException: java.lang.NullPointerException
at com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:140)
at com.sun.grizzly.http.TaskBase.run(TaskBase.java:193)
at com.sun.grizzly.http.TaskBase.execute(TaskBase.java:175)
at com.sun.grizzly.arp.DefaultAsyncHandler.handle(DefaultAsyncHandler.java:145)
at com.sun.grizzly.arp.AsyncProtocolFilter.execute(AsyncProtocolFilter.java:210)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at com.sun.grizzly.arp.AsyncProcessorTask.obtainAndSetThreadAttachment(AsyncProcessorTask.java:230)
at com.sun.grizzly.arp.AsyncProcessorTask.enableTimeout(AsyncProcessorTask.java:223)
at com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:127)
... 14 more
|#]我已经在玻璃鱼上发布了这个命令:
asadmin set configs.config.server-config.network-config.protocols.protocol.http-listener-1.http.websockets-support-enabled=true看起来Spring在某个地方放松了请求对象,这似乎是空的。也许我必须在web.xml文件中做一些与URL /实时通道相关的配置?
如果我删除websocket注册WebSocketEngine.getEngine().register(this);,一切都正常,但是websocket,当然,不再工作了。
其他例外
有时,应用程序还抛出其他异常:
[#|2017-11-24T14:47:11.655+0100|SEVERE|glassfish3.1.2|com.sun.grizzly.config.GrizzlyServiceListener|_ThreadID=123;_ThreadName=Thread-2;|java.lang.NullPointerException
at com.sun.grizzly.arp.AsyncProcessorTask.obtainAndSetThreadAttachment(AsyncProcessorTask.java:230)
at com.sun.grizzly.arp.AsyncProcessorTask.enableTimeout(AsyncProcessorTask.java:223)
at com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:127)
at com.sun.grizzly.http.TaskBase.run(TaskBase.java:193)
at com.sun.grizzly.http.TaskBase.execute(TaskBase.java:175)
at com.sun.grizzly.arp.DefaultAsyncHandler.handle(DefaultAsyncHandler.java:145)
at com.sun.grizzly.arp.AsyncProtocolFilter.execute(AsyncProtocolFilter.java:210)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:745)
|#]
[#|2017-11-24T14:47:11.657+0100|INFO|glassfish3.1.2|com.sun.grizzly.config.GrizzlyServiceListener|_ThreadID=123;_ThreadName=Thread-2;|Processor exception
java.lang.RuntimeException: java.lang.NullPointerException
at com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:140)
at com.sun.grizzly.http.TaskBase.run(TaskBase.java:193)
at com.sun.grizzly.http.TaskBase.execute(TaskBase.java:175)
at com.sun.grizzly.arp.DefaultAsyncHandler.handle(DefaultAsyncHandler.java:145)
at com.sun.grizzly.arp.AsyncProtocolFilter.execute(AsyncProtocolFilter.java:210)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at com.sun.grizzly.arp.AsyncProcessorTask.obtainAndSetThreadAttachment(AsyncProcessorTask.java:230)
at com.sun.grizzly.arp.AsyncProcessorTask.enableTimeout(AsyncProcessorTask.java:223)
at com.sun.grizzly.arp.AsyncProcessorTask.doTask(AsyncProcessorTask.java:127)
... 14 more
|#]更新
如果我为所有URL定义了一个HandlerInterceptor,并添加了断点,我可以看到异常在之后、preHandle钩子的执行和postHandle钩子的执行之后(在这两个函数中HttpServletRequest对象都是有效的)引发的。
发布于 2017-12-13 15:43:12
几天后,我设法解决了这个问题,用GrizzlyFramework1.9.50升级到Glassfish Server 3.1.2.2,因为GrizzlyFramework1.9.46似乎不适用于web套接字。
https://stackoverflow.com/questions/47474165
复制相似问题