users@grizzly.java.net

Re: Ping/Pong mechanism in Grizzly 2.1.8 WebSocket API

From: Philipp Tarasiewicz <justphilmusic_at_googlemail.com>
Date: Thu, 12 Jan 2012 00:20:22 +0100

The changes look good!
My heartbeats code runs like clockwork. :-)
Good work!

Philipp

2012/1/11 Philipp Tarasiewicz <justphilmusic_at_googlemail.com>

> Hi Ryan,
>
> I will check out the changes as soon as I'm back home.
>
> Wednesday always means having to stay long at work...
>
>
> But, thank you very much for your efforts! :-)
>
> Philipp
>
>
> 2012/1/11 Ryan Lubke <ryan.lubke_at_oracle.com>
>
>> Hi Phillipp,
>>
>> Just wanted to follow up to see if the changes we made yesterday
>> addressed your issues.
>>
>> Let us know.
>>
>> -rl
>>
>>
>> On 1/10/12 6:01 AM, Philipp Tarasiewicz wrote:
>>
>> Ok, I understand.
>>
>> Regarding the mentioned unidirectional heartbeats, I think that besides
>> ping() a pong() method is equally meaningful.
>>
>>
>> In the meantime, would you (or Ryan) mind posting some code showing how
>> to send a ping using the current (2.1.8) API?
>> Would be very helpful since then I could run some tests with the
>> ping/pong feature.
>>
>>
>> Thanks! And keep on doing such a good work! :-)
>>
>> 2012/1/10 Justin Lee <jlee_at_antwerkz.com>
>>
>>> 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
>>>
>>
>>
>>
>