users@grizzly.java.net

Re: Ping/Pong mechanism in Grizzly 2.1.8 WebSocket API

From: Justin Lee <jlee_at_antwerkz.com>
Date: Tue, 10 Jan 2012 08:45:12 -0500

And if you ever find yourself doing something like "new
DataFrame(...)," you're almost certainly doing it wrong. The API was
designed such that you'd never have to do deal with DataFrame
directly. But, yeah, it looks like the we probably could use a ping()
on the websocket class.

On Tue, Jan 10, 2012 at 8:00 AM, Ryan Lubke <ryan.lubke_at_oracle.com> wrote:
> 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>
>>
>> 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>
>>>
>>> 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>
>>>>
>>>> On 1/9/12 7:19 AM, 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
>>>>
>>>>
>>>
>>
>>
>
>



-- 
You can find me on the net at:
http://antwerkz.com
http://antwerkz.com/+
http://antwerkz.com/linkedin
http://antwerkz.com/twitter