9 Replies Latest reply: May 13, 2009 11:29 AM by sneakyimp RSS

    movieclip movement triggered by socket event, need more frequent rendering

    sneakyimp Community Member

      I have a flash project that's implementing a simple two player game.  I have added an enterFrame function to my main movie which listens for keyboard activity in order to move a cowboy gunslinger.  Whenever the cowboy moves, I send a message over a socket to a server which dispatches the movement to the other connected client.  This works pretty well, however, the movement messages tend to arrive in clumps which results in jumpy animation of my cowboy on my opponents screen and jumpy animation of his cowboy on my screen.  To illustrate, i put a trace in my enterFrame function because I am imagining that this function will run roughly once each time my main movie renders the screen.  I also put a trace statement in my function that responds to network traffic and moves the remote player's cowboy on my screen.  Here's the output:

      enter frame:4
      enter frame:4
      enter frame:4
      client movePlayer running
      client movePlayer running
      client movePlayer running
      client movePlayer running
      client movePlayer running
      enter frame:4
      enter frame:4
      enter frame:4
      enter frame:4
      enter frame:4
      enter frame:4
      client movePlayer running
      client movePlayer running
      client movePlayer running
      client movePlayer running
      client movePlayer running
      client movePlayer running
      enter frame:4
      enter frame:4
      enter frame:4
      enter frame:4
      

      As you can see, I'll get several messages in a row from the remote client which instruct me to move their cowboy ('client MovePlayer running') and they will all run in a row before the screen updates.

       

      I'm guessing I should be using something like updateAfterEvent but this method is only provided by Mouse, Timer, and Keyboard events.

       

      So a few questions:

      1) Can someone recommend a good approach to force a screen render each time an incoming movePlayer event arrives over the socket?  It's important to note that my function for handling these events has no visibility to the original socket data event.

      2) Am I right in understanding that the enterFrame function of my main movie happens once each time my movie is rendered?  Is there some more accurate event to which I could attach a trace message so that I better understand the relative frequency of the render events and the socket events?

      3) Does firing an updateAfterEvent call force onEnterFrame events to happen more frequently?  I'm worried about destroying performance by inadvertently firing more enterFrames which would fire more socket events which would fire more enterFrames, etc., etc.

       

      Any help would be much appreciated.

        • 1. Re: movieclip movement triggered by socket event, need more frequent rendering
          sneakyimp Community Member

          I have noticed that while my server appears to be writing bytes on a regular basis, roughly every 30 or 40 milliseconds:

          51 bytes sent at 1242146737.69
          43 bytes sent at 1242146737.72
          43 bytes sent at 1242146737.76
          43 bytes sent at 1242146737.79
          43 bytes sent at 1242146737.82
          43 bytes sent at 1242146737.86
          43 bytes sent at 1242146737.89
          43 bytes sent at 1242146737.92
          52 bytes sent at 1242146737.96
          51 bytes sent at 1242146739.46
          43 bytes sent at 1242146739.49
          44 bytes sent at 1242146739.52
          44 bytes sent at 1242146739.56
          44 bytes sent at 1242146739.59
          44 bytes sent at 1242146739.62
          44 bytes sent at 1242146739.66
          53 bytes sent at 1242146739.69
          

           

          the socketData event is only firing every 150-200 milliseconds and these packages arrive in clumps:

          * socketDataHandler running at 1242153515.5
          client.movePlayer running at 1242153515.515
          * socketDataHandler running at 1242153515.703
          client.movePlayer running at 1242153515.703
          client.movePlayer running at 1242153515.703
          client.movePlayer running at 1242153515.703
          client.movePlayer running at 1242153515.703
          client.movePlayer running at 1242153515.703
          * socketDataHandler running at 1242153515.89
          client.movePlayer running at 1242153515.89
          client.movePlayer running at 1242153515.906
          client.movePlayer running at 1242153515.906
          client.movePlayer running at 1242153515.906
          client.movePlayer running at 1242153515.906
          client.movePlayer running at 1242153515.906
          * socketDataHandler running at 1242153516.093
          client.movePlayer running at 1242153516.109
          client.movePlayer running at 1242153516.109
          client.movePlayer running at 1242153516.109
          client.movePlayer running at 1242153516.109
          client.movePlayer running at 1242153516.109
          • 2. Re: movieclip movement triggered by socket event, need more frequent rendering
            Raymond Basque Community Member

            Could it be your socket server is buffering the packets? TCP header is 40 bytes, and your packet sizes range from 43-53 bytes. Could be Nagle's algorithm kicking in. Just a guess, but if that's the case you should be able to turn it off and sent all your small packets immediately.

            • 3. Re: movieclip movement triggered by socket event, need more frequent rendering
              sneakyimp Community Member

              Thanks for your response.

               

              The length of those messages is reported from within my server just after the RPC message has been serialized into AMF3 format so the TCP header doesn't factor.  Basically, it's the return value reported by php's socket_write function.  It corresponds pretty much exactly to a complete RPC packet containing a short string and a few floating point values.

              • 4. Re: movieclip movement triggered by socket event, need more frequent rendering
                sneakyimp Community Member

                It just occurred to me that this clustering of packets may be occurring at some level between PHP and the network card.  I *really* appreciate you pointing out this possibility.  I'm looking into it.

                • 5. Re: movieclip movement triggered by socket event, need more frequent rendering
                  Raymond Basque Community Member

                  Yeah. Was just a thought. It's normal for TCP to buffer packets and usually has no affect on performance. Here's a bit of reading material:

                   

                  http://www.unixguide.net/network/socketfaq/

                   

                  • 6. Re: movieclip movement triggered by socket event, need more frequent rendering
                    sneakyimp Community Member

                    That reading looks pretty good.  Especially this.

                    • 7. Re: movieclip movement triggered by socket event, need more frequent rendering
                      Raymond Basque Community Member

                      Yeah. Doesn't hurt to try TCP_NODELAY.

                      • 8. Re: movieclip movement triggered by socket event, need more frequent rendering
                        sneakyimp Community Member

                        PROBLEM SOLVED YEAH.  It was indeed a server-side issue relating to Nagle's algorithm.  I fixed the problem by setting an additional socket option (TCP_NODELAY).  Now I'm getting awesomely prompt position updates and very smooth movement.  It's worth noting that there is usually a hiccup at the beginning but then everything is smooth sailing.

                        socketDataHandler running at 1242238803.234
                        client.movePlayer running at 1242238803234
                        client.movePlayer running at 1242238803250
                        client.movePlayer running at 1242238803250
                        client.movePlayer running at 1242238803250
                        client.movePlayer running at 1242238803250
                        client.movePlayer running at 1242238803250
                        client.movePlayer running at 1242238803250
                        client.movePlayer running at 1242238803265
                        socketDataHandler running at 1242238803.312
                        client.movePlayer running at 1242238803312
                        socketDataHandler running at 1242238803.343
                        client.movePlayer running at 1242238803343
                        socketDataHandler running at 1242238803.375
                        client.movePlayer running at 1242238803375
                        socketDataHandler running at 1242238803.406
                        client.movePlayer running at 1242238803406
                        socketDataHandler running at 1242238803.437
                        client.movePlayer running at 1242238803453
                        socketDataHandler running at 1242238803.468
                        client.movePlayer running at 1242238803484
                        socketDataHandler running at 1242238803.5
                        client.movePlayer running at 1242238803515
                        socketDataHandler running at 1242238803.546
                        client.movePlayer running at 1242238803546
                        socketDataHandler running at 1242238803.578
                        client.movePlayer running at 1242238803578

                        BAng!  position updates every 30 milliseconds or so.  Pretty awesome. Thank you SO MUCH for the suggestion, Raymond.