Re: Intercepting WebSocket ping messages

2017-03-31 Thread Mark Thomas
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: 

Re: Intercepting WebSocket ping messages

2017-03-31 Thread Robert Lewis
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)


Re: Intercepting WebSocket ping messages

2017-03-31 Thread Mark Thomas
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




Intercepting WebSocket ping messages

2017-03-30 Thread Robert Lewis
Is there a way to intercept a ping message to send a pong? I need to do
this synchronize sends to the endpoint.

I tried

session.addMessageHandler(new
javax.websocket.MessageHandler.Whole() {

@Override
public void onMessage(PongMessage message) {
System.out.println("hi");
}

});


And

@OnMessage public void onPong(PongMessage message) {}