簡體   English   中英

使用Glassfish 3.1.2和Spring實施Grizzly Websockets

[英]Implementing Grizzly Websockets with Glassfish 3.1.2 and Spring

我正在嘗試向在Glassfish 3.1.2和Spring 4.1.5-RELEASE上運行的舊應用程序添加網絡套接字通知。 實施Spring的websocket無法正常工作,因為它需要GlassFish 4.1+,並且我們無法升級應用程序服務器。 我使用的是Grizzly網絡套接字1.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對象(此) (4)對/ realtime-channel的每個請求將由WebSocketApplication調用OnMessage回調處理。 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失去了REQUEST對象,那似乎是空的。 也許我必須在與URL / realtime-channel相關的web.xml文件中進行某種配置?

如果我刪除了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
|#]

更新

如果我定義HandlerInterceptor所有網址,並添加斷點,我可以看到異常的執行提高preHandle鈎和執行后postHandle鈎(在兩個函數HttpServletRequest對象是有效的)。

幾天后,我設法解決了使用Grizzly Framework 1.9.50升級到Glassfish Server 3.1.2.2的問題,因為Grizzly Framework 1.9.46似乎不適用於Web套接字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM