[prev in list] [next in list] [prev in thread] [next in thread]
List: tomcat-user
Subject: Re: Intercepting WebSocket ping messages
From: Mark Thomas <markt () apache ! org>
Date: 2017-03-31 15:25:19
Message-ID: cb6c303a-78f6-340a-724a-490c6e9c2cc0 () apache ! org
[Download RAW message or body]
On 31/03/17 15:03, Robert Lewis wrote:
> We have a Server <-> Client connection. The client periodically sends pings
> to the server, and Tomcat will respond with a sendPong() on a container
> thread, but the same instance of WsRemoteEndpointImplServer we are actively
> sending writes on. WsRemoteEndpointImplServer.doWrite() does not seem
> thread safe, so I have a feeling that tomcat handling the pongs on a
> separate thread is interfering with our constant calls to doWrite() on the
> same instance of WsRemoteEndpointImplServer.
>
> If I could synchronize the pong with our application application calls to
> sendBinary(), I could fix a potential problem. If it is not supported,
> completely understand. I apologize as I have yet to time this perfectly
> where the calls do overlap. Do you happen to know if these calls will be
> synchronized by the container?
Yes, Tomcat should handle this for you.
> I attached logging into WsRemoteEndpointImplServer (for doWrite() and
> onWritePossible()), this includes start and end of the function calls, and
> each start will show a hashcode of the WsRemoteEndpointImplServer instance,
> and a hashcode of the SendHandler instance (endpointhash:handlerhash),
> where two threads are making what seems not so thread safe calls.
"seems"? Can you be more precise. To be clear, if you can show exactly
what the problem is / how the thread-safety problem occurs then you
stand a much greater chance of it being fixed.
Mark
> The first
> thread is the application calling down to doWrite() (locked at the
> application level) and the second thread is a container thread responding
> to a ping:
>
> Thread 1 (Application Synchronized)
> --------------------------------------------
> http-nio-8443-exec-5: doWrite (start) 909703826:81194941
> java.lang.Thread.getStackTrace(Thread.java:1556)
>
> org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:81)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:453)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessage(WsRemoteEndpointImplBase.java:341)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:273)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendBytes(WsRemoteEndpointImplBase.java:134)
>
> org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendBinary(WsRemoteEndpointBasic.java:43)
>
> com.thingworx.communications.server.connection.jsr356.Jsr356ServerConnection.sendBinaryMessage(Jsr356ServerConnection.java:613)
>
> com.thingworx.communications.common.contexts.BaseContext.write(BaseContext.java:95)
>
> com.thingworx.communications.common.messaging.ThingworxMessage.writeContent(ThingworxMessage.java:39)
>
> com.thingworx.communications.server.modules.ServerCommunicationModuleBase.registerServerConnection(ServerCommunicationModuleBase.java:141)
>
> com.thingworx.communications.server.connection.jsr356.Jsr356ServerConnection.registerConnection(Jsr356ServerConnection.java:332)
>
> com.thingworx.communications.server.connection.jsr356.Jsr356ServerConnection.onMessage(Jsr356ServerConnection.java:304)
> sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> java.lang.reflect.Method.invoke(Method.java:498)
>
> org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeBase.onMessage(PojoMessageHandlerWholeBase.java:80)
>
> org.apache.tomcat.websocket.WsFrameBase.sendMessageBinary(WsFrameBase.java:592)
>
> org.apache.tomcat.websocket.WsFrameBase.processDataBinary(WsFrameBase.java:549)
> org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:301)
>
> org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:131)
>
> org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:71)
>
> org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:185)
>
> org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:198)
>
> org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:96)
>
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:664)
>
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
>
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
>
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
>
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
>
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
> java.lang.Thread.run(Thread.java:745)
> http-nio-8443-exec-5: onWritePossible (start) 909703826:81194941
> java.lang.Thread.getStackTrace(Thread.java:1556)
>
> org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.onWritePossible(WsRemoteEndpointImplServer.java:97)
>
> org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:89)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:453)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessage(WsRemoteEndpointImplBase.java:341)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:273)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendBytes(WsRemoteEndpointImplBase.java:134)
>
> org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendBinary(WsRemoteEndpointBasic.java:43)
>
> com.thingworx.communications.server.connection.jsr356.Jsr356ServerConnection.sendBinaryMessage(Jsr356ServerConnection.java:613)
>
> com.thingworx.communications.common.contexts.BaseContext.write(BaseContext.java:95)
>
> com.thingworx.communications.common.messaging.ThingworxMessage.writeContent(ThingworxMessage.java:39)
>
> com.thingworx.communications.server.modules.ServerCommunicationModuleBase.registerServerConnection(ServerCommunicationModuleBase.java:141)
>
> com.thingworx.communications.server.connection.jsr356.Jsr356ServerConnection.registerConnection(Jsr356ServerConnection.java:332)
>
> com.thingworx.communications.server.connection.jsr356.Jsr356ServerConnection.onMessage(Jsr356ServerConnection.java:304)
> sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> java.lang.reflect.Method.invoke(Method.java:498)
>
> org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeBase.onMessage(PojoMessageHandlerWholeBase.java:80)
>
> org.apache.tomcat.websocket.WsFrameBase.sendMessageBinary(WsFrameBase.java:592)
>
> org.apache.tomcat.websocket.WsFrameBase.processDataBinary(WsFrameBase.java:549)
> org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:301)
>
> org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:131)
>
> org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:71)
>
> org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:185)
>
> org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:198)
>
> org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:96)
>
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:664)
>
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
>
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
>
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
>
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
>
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
> java.lang.Thread.run(Thread.java:745)
> http-nio-8443-exec-5: clearHandler (start) 909703826:81194941
> http-nio-8443-exec-5: clearHandler (end)
> http-nio-8443-exec-5: onWritePossible (end)
> http-nio-8443-exec-5: doWrite (end)
>
> Thread 2 (Tomcat, Unsyncronized?)
> --------------------------------------------
> http-nio-8443-exec-10: doWrite (start) 909703826:1000491596
> java.lang.Thread.getStackTrace(Thread.java:1556)
>
> org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:81)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:453)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessage(WsRemoteEndpointImplBase.java:341)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:273)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendPong(WsRemoteEndpointImplBase.java:186)
>
> org.apache.tomcat.websocket.WsRemoteEndpointBase.sendPong(WsRemoteEndpointBase.java:62)
>
> org.apache.tomcat.websocket.WsFrameBase.processDataControl(WsFrameBase.java:351)
> org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:290)
>
> org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:131)
>
> org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:71)
>
> org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:185)
>
> org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:198)
>
> org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:96)
>
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:664)
>
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
>
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
>
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
>
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
>
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
> java.lang.Thread.run(Thread.java:745)
> http-nio-8443-exec-10: onWritePossible (start) 909703826:1000491596
> java.lang.Thread.getStackTrace(Thread.java:1556)
>
> org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.onWritePossible(WsRemoteEndpointImplServer.java:97)
>
> org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:89)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:453)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessage(WsRemoteEndpointImplBase.java:341)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:273)
>
> org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendPong(WsRemoteEndpointImplBase.java:186)
>
> org.apache.tomcat.websocket.WsRemoteEndpointBase.sendPong(WsRemoteEndpointBase.java:62)
>
> org.apache.tomcat.websocket.WsFrameBase.processDataControl(WsFrameBase.java:351)
> org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:290)
>
> org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:131)
>
> org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:71)
>
> org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:185)
>
> org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:198)
>
> org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:96)
>
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:664)
>
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
>
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
>
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
>
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
>
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
> java.lang.Thread.run(Thread.java:745)
> http-nio-8443-exec-10: clearHandler (start) 909703826:1000491596
> http-nio-8443-exec-10: clearHandler (end)
> http-nio-8443-exec-10: onWritePossible (end)
> http-nio-8443-exec-10: doWrite (end)
>
>
> On Fri, Mar 31, 2017 at 9:01 AM, Mark Thomas <markt@apache.org> wrote:
>
> > On 30/03/17 21:13, Robert Lewis wrote:
> > > Is there a way to intercept a ping message to send a pong?
> >
> > The API doesn't support this.
> >
> >
> > > I need to do this synchronize sends to the endpoint.
> >
> > Could you clarify your requirement? Tomcat should handle pong messages
> > automatically for you (as required by the spec).
> >
> > Mark
> >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> > For additional commands, e-mail: users-help@tomcat.apache.org
> >
> >
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic