users@grizzly.java.net

Re: Ping/Pong mechanism in Grizzly 2.1.8 WebSocket API

From: Ryan Lubke <ryan.lubke_at_oracle.com>
Date: Tue, 10 Jan 2012 05:00:31 -0800

On 1/10/12 3:26 AM, Philipp Tarasiewicz wrote:
> Ah okay, I see.
>
> So, in the case I want to perform ping/pong keepalives, the question
> is: How can I send a valid PingFrame from the server to the client?
> (Seems like I was too cheeky... :-))
>
>
> However, the Pong chapter in the WebSocket RFC (ch. 5.5.3,
> http://www.rfc-editor.org/rfc/rfc6455.txt) says something like:
> "A Pong frame MAY be sent unsolicited. This serves as a unidirectional
> heartbeat. A response to an unsolicited Pong frame is not expected."
>
> That's exactly what I want to achieve with the client code from my
> last snippet. The client shall send heartbeats to the server at a
> specified interval.
> Consequently, I need to find a way to send valid PongFrames from the
> client to the server.
> Any hints on this one? :-)
Looks like we'll need to work on that from our end. I'll follow up once
something is ready.
>
> Thanks in advance!
> Philipp
>
> 2012/1/10 Ryan Lubke <ryan.lubke_at_oracle.com
> <mailto:ryan.lubke_at_oracle.com>>
>
> On 1/9/12 2:42 PM, Philipp Tarasiewicz wrote:
>> It turned out that I still have complications to send a valid
>> PongFrame while implementing a heart-beat mechanism on my
>> websocket client.
>>
>> Here is the relevant snippet:
>>
>> // My WebSocketApplication subclass
>>
>> @Override
>> public void onPong(WebSocket socket, byte[] bytes) {
>> System.out.println("*** *** onPong() *** ***");
>> super.onPong(socket, bytes);
>> }
>>
>> // My client's PongFrame send invocation
>> webSocket.send(new DataFrame(new PongFrameType(), new byte[0],
>> true).getBytes());
> That's not going to work since the binary representation of the
> frame you create will be the payload and not the frame itself.
>
> If the Server is sending the ping, the pong should be sent
> automatically so you shouldn't have to do this.
>
>>
>> Syntax highlighted version:
>> http://pastebin.com/ADSGKBxS
>>
>>
>> All I want to accomplish is to let the client send a valid
>> PongFrame, such that my overriden onPong() callback gets invoked
>> on the server side.
>>
>> Would you be so kind and provide a snippet showing a sending of a
>> valid PongFrame? :-)
>>
>> 2012/1/9 Philipp Tarasiewicz <justphilmusic_at_googlemail.com
>> <mailto:justphilmusic_at_googlemail.com>>
>>
>> Hi Ryan,
>>
>> I haven't any code that is worth mentioning, since I've
>> obviously misinterpreted the related API docs.
>>
>> My initial thoughts after having studied the docs were like:
>> Grizzly automatically performs ping/pong cycles every x
>> seconds to maintain the connection to every connected remote
>> client and correspondingly invokes the related callback
>> methods in the WebSocketApplication class.
>> - onPing(WebSocket socket, byte[] bytes) : Server is about
>> to ping WebSocket 'socket' by sending 'bytes' bytes.
>> - onPong(WebSocket socket, byte[] bytes) : Server has
>> received pong information 'bytes' from remote client
>> connected to WebSocket 'socket'.
>>
>> So, I've overriden these methods in my WebSocketApplication
>> subclass (just for logging purpose), started the server,
>> connected a client to it and have been expecting that
>> server/client will automatically perform ping/pong cycles
>> every x seconds.
>>
>>
>> But finally, after having read your and Justin's responses +
>> having a closer look at your corresponding code (just cloned
>> the repo), it is completely enlightening that it could not
>> work this way.
>>
>> In particular, I've realized how you send the ping / pong
>> frames. Consequently, it shouldn't be a big deal for me to
>> implement the behavior that I had initially expected.
>>
>> Nevertheless, I will also log a feature request. :-)
>>
>>
>>
>> There is one more question I'm interested in. But, I should
>> probably ask it in a new thread since it does not related to
>> this topic.
>>
>> Thank you guys for your help!
>>
>> Phil
>>
>>
>> 2012/1/9 Ryan Lubke <ryan.lubke_at_oracle.com
>> <mailto:ryan.lubke_at_oracle.com>>
>>
>> On 1/9/12 7:19 AM, justphilmusic_at_googlemail.com
>> <mailto:justphilmusic_at_googlemail.com> wrote:
>>
>> Hi Ryan!
>>
>> Until now I've just played around with the
>> WebSocketClient included in
>> Grizzly's 2.1.8 WebSocket API. So, it's the websocket
>> version that the
>> WebSocketClient class is using.
>> I haven't used a brower yet.
>>
>> To go back to your original question, I've locally tested
>> that pings are
>> responded to automatically, however, I'm making some
>> changes to
>> make sending pings a little more straight forward.
>>
>> Can you share your code? Would like to see what you're
>> doing different.
>>
>>
>> The question is:
>> Does Grizzly's WebSocket implementation perform any
>> connection
>> maintainance / heart-beating under the hood or do I
>> have to implement
>> the logic by myself?
>>
>> At this point, there is no heart-beat feature. However,
>> it probably wouldn't
>> be a bad feature to offer. I would recommend logging a
>> feature request.
>>
>>
>>
>> Best regards,
>> Phil
>>
>>
>>
>>
>
>