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? 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. 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 <ma...@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-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org > >