🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Wi-Fi Latency (Local Network)

Started by
7 comments, last by hplus0603 8 years ago

Hello,

I'm working an a time sensitive project over Wi-Fi. For my example, imagine a button on two mobile devices (same devices) connected to a local Wi-Fi router as well as a PC connected to that same router. Everything is offline and locally connected. The PC is hardwired.

I am trying to find the best way to use Wi-Fi so that the PC application will know which mobile device's button was pressed 'first'. Like who buzzed in first in a game show for example.

I understand enough to know the limitations of Wi-Fi, but I'm curious if anyone has any suggestions on how to make this work with extreme precision? Ideally, I'd like the mobile devices to sync up to the CPU tick time and then send a packet containing the exact tick the mobile device was on when the button was pressed then when the PC gets both packets of data, the PC can evaluate the data and return the results.

Is this possible? Or is there any other ideas?

Thanks!

Advertisement
Why so complicated?

Send an UDP datagram out as soon as the user presses the button. If tampered client cheating isn't a concern, send another one 50ms later (but do include a "this is a resend" bit) just for the odd case that the packet got lost. That shouldn't happen anyway, but you never know. If a resend packet is received but no original, assume the original packet being 50ms earlier. Again, this works only under the assumption "no tampered clients".

The first datagram to be received on the server wins. Done.

That's not perfect, but it is pretty much as good as you can get. Everything else which is a lot more complicated isn' really much better.

Synchronized clocks suck. Synchronized high resolution clocks suck a lot. Synchronization and wireless in the same sentence sucks even more. I would want to avoid any such thing if I had any chance.

Additionally, you might find that the latency added by different touch-screen devices is actually larger than the latency involved across WiFi.

I agree. Use UDP broadcast on the local subnet. Send three or so packets per button press, at time T, T+15ms, and T+60 ms, with a "this is packet N" counter.

Alternatively, have the PC echo back to the network each time it receives a packet, and have the client keep sending every 15 milliseconds until it sees the echo. That would be even simpler!

UDP broadcast on the local subnet is generally easiest by turning on SO_BROADCAST and sending to the IP address 0xffffffff (255.255.255.255)

However, if your wifi access point routes (as oppoed to switches) between wired and wireless, you may need to actually use the network address -- if your network is 192.168.1.0/24, then the network address is 192.168.1.255, for example. Finding the network address of a host is actually annoying and platform specific, so start with 255.255.255.255 and hopefully it works fine (it usually does, once SO_BROADCAST is turned on.)

enum Bool { True, False, FileNotFound };

Thanks for the responses!

Does anyone here think that a router could cause a long enough delay such that if you pressed a button on both devices (same mobile device hardware-wise) but one device you pressed slightly faster, that the router could become congested and deliver the wrong packet first? Or is any issues like that really so fast (sub 10 milliseconds) that its imperceptible?

Should I just use TCP instead of sending out my own multiple packets as well?

Thanks again for the help!

Does anyone here think that a router could cause a long enough delay such that if you pressed a button on both devices (same mobile device hardware-wise) but one device you pressed slightly faster, that the router could become congested and deliver the wrong packet first? Or is any issues like that really so fast (sub 10 milliseconds) that its imperceptible?


Sure, there are plenty of qualifiers in there and any COULD happen.

Also, what do you mean by "deliver the wrong packet first"? Nothing in Ethernet I'm aware of requires specific ordering when multiple devices are involved.

Since they come through the network card sequentially, one of them is going to come before the other. Many different things across a network can cause one of them to arrive before the other, possibly in a different order from the instant they were pressed.

Also, what do you mean by "deliver the wrong packet first"?

I mean if user A hits their button first, but shortly there after user B hits there button (I'm talking a 10th of a second). Could packet A hit the router, sit because the router is 'busy' and packet B hit the router and get filtered out to the PC first, then packet A.

Also, when you say things COULD happen or delays MIGHT happen, how much time are we talking? 1-10 millseconds, 10-100 milliseconds, seconds? Obviously if we're talking a few milliseconds then that's acceptable, but if we're talking a few seconds on occasion then things won't work.

Thanks!

Yes, it could happen.

If you can trust the clients, you can make it less likely to happen by broadcasting the current server time on regular intervals, and have the clients adjust their local clocks (see NTP) and include a timestamp in each packet.

enum Bool { True, False, FileNotFound };

Note that with a time stamp, it is still quite likely that they arrive in a different order. Many different factors can cause them to arrive on your machine in a different order than the buttons were physically pressed. You'd get one packet with a time stamp of 12345, then get a second packet with a time stamp of 12310.

Even if you rely on time stamps, clocks drift and clocks on computers still represent an interval generally on the order of microseconds. You've got to figure out how close is good enough.

Nothing you are likely to implement will be perfect, short of carefully building custom hardware with exactly identical lengths of wire and exactly identical lengths of circuitry and with a specialized switch that flips when current first arrives from either physical device.

with a time stamp, it is still quite likely that they arrive in a different order.

Yes, so you have to wait for some amount of time (200 milliseconds? Until you've heard from both?) until you declare a winner.

Keep sending from both clients with a "nothing pressed" status is quite useful to know that the clients are in fact visible to the server, and vice versa.

clocks drift and clocks on computers still represent an interval generally on the order of microseconds

Yes. The drift should be compensated for using the periodic updates the server sends out. NTP has this down pat, but you can do a more ghetto version on your own if you want.

Luckily, OP has a totally doable upper bound on precision:

if we're talking a few milliseconds then that's acceptable

So, one simple implementation would be:

- server broadcasts clock packets 10 times a second with server high-resolution time stamp (based on QueryPerformanceCounter, CLOCK_MONOTONIC_RAW, or similar.)

- clients broadcast state 10 times a second, with either "nothing pressed, last server timestamp was X" or "I saw a button, X amount of time after last timestamp, which was Y"

- server makes determination about winner when it has received updates from both clients from a time stamp AFTER the time claimed by at least one client (this will generally be within 100 milliseconds)

To compensate for jitter in receiving the time stamps, the clients should probably update their "server offset estimate" by perhaps 10% of the delta, rather than the full delta, for each received timstamp. (This is the "ghetto NTP alternative" option)

Note: This doesn't immediately send a packet on button press, but instead sends a continual stream of state, and makes the server make a determination when it can be as sure as possible. If the server needs to make a decision sooner, you have to trade "tolerance to delay" against" quickness of decision."

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement