dmccuskey / dmc-websockets

Corona SDK client library for the WebSocket protocol (RFC6455)
MIT License
11 stars 7 forks source link

handle pong messages (allows to implement application level timeouts) #2

Open chkuendig opened 9 years ago

chkuendig commented 9 years ago

Hi, i added an additional event ( WebSocket.ONPONG) so i can handle connection timeouts properly in my app. Cheers

dmccuskey commented 9 years ago

hey Christian, thanks for the PR. i think having control over PONG would be useful (eg, how often sent, how many bounces, etc). so i am curious to know what you're doing with the PONG messages in your app. cheers, dmc

chkuendig commented 9 years ago

Hi DMC,

I use it to detect connection timeouts (and get to calculate latency timings for free ). As a nice side-effect, heroku won't kill my idle connections anymore.

    function startPingTimer(timeout)
      local pings_until_timeout = 2
      local interval = (1000*timeout)/pings_until_timeout

      if(self.ping_timer) then
        self:stopPingTimer()
      end
        self.pingssent = 0

        self.ping_timer = timer.performWithDelay( interval, function()
          if(self.pingssent > pings_until_timeout ) then
            self:disconnect("Connection Timeout")
          else
            self.socket:_sendPing(""..socket.gettime())
            self.pingssent = self.pingssent+1
          end
        end, -1 )
    end
    local function eventHandler( event )
        local evt_type = event.type
       ...
       if evt_type == self.socket.ONPONG then
            local time = socket.gettime()
            print("received pong, latency (ms) "..(time-event.message.data)*1000)
            self.pingssent = 0
        end
    end
    self.socket:addEventListener( self.socket.EVENT, eventHandler )

(Inspired by http://stackoverflow.com/questions/25352111/nodejs-einaros-ws-connection-timeout which is what I run on the server side for the same reasons)

Cheers Christian

dmccuskey commented 9 years ago

i think this functionality is great and should be already in the module. right now there's no user control over PING, but there should be. i would implement it a little differently, mostly to hide PING/PONG from the user, since those are lower-level websocket events.

  1. add functionality/defaults:
    • add active PING from the library, say every 3000ms default
    • have a number of retries (you show 2)
  2. add to params, for user to set their own values, something like: keepalive=1000 retries=4
  3. calculate latency automatically, put in read-only property: connection.latency

do you wanna code that ? :)

cheers, dmc

added to #3

chkuendig commented 9 years ago

Hi DMC, at the moment I don't have the time, but i agree it would be nice to have this in the library. I will try to implement it when I find the time.

Regards

PS: I fixed a little bug in the sample above, moving the multiplication by 1000 from the timer.performWithDelay( interval*1000 to local interval = (timeout*1000)/pings_until_timeout. Otherwise we get a lot of rounding issues.