Sergey Maslov Sergey Maslov - 1 month ago 9
Android Question

Wi-fi P2P. Inform all peers available of some event

The problem: I'm making an offline-multiplayer android game, where people can create or join a room and play together via Wi-fi. Consider the situation when a user creates a room and he (of course) has to inform all other users that there is a room available. So the question is "How?".I've read about 1000 times this
and this.
It's written there that in order to send some data to another device, one of them should be a server and the other one a client. Client sends some info to the server, server accepts it. So, does it mean that I have to make all "players" servers and the "room creator" should become a client? This sounds crazy. Please help, may be I'm reading the wrong docs?

Answer

First of all you need to remember that if you do decide to use WiFiP2P in your project you will need to prepare yourself for some difficult time. Unfortunately (as you already might have noticed :)) WiFiP2P Android's official documentation is not that great. Different devices behave in different ways (e.g. they call some WifiP2P events in different order) and docs don't cover it at all. Achieving a stable connection requires introducing unconventional and sometimes drastic measures. Obtaining a WifiP2P connection is inseperably linked with displaying a system window (asking if you really want to connect to a device).

There are few things you need to consider before you start implementing a WifiP2P solution:

  1. Will players of your game be able to connect to more than one room simultaneously?
  2. Will players of your game be able to detect new room while connected to another?
  3. Will players of your game be able to name their rooms with "human-readable" names? And those names would be used by other users (not the creator of the room) to choose a room to which they would like to connect to?

Scenario A:

If you answered "Yes" to question 1. or 2., you seriously need to consider if you really want to use WifiP2P. WifiP2P (Android's implementation of Wifi-Direct) does not really fit your needs. Using WifiP2P would probably mean that a room owner creates a WifiP2P-group and any person who wants to join the room must connect to this WifiP2p-group. The problem is Android does not allow for a single device to join multiple groups at the same time (which also means it does not allow to create multiple groups at the same time). Detecting changes in available WiFiP2P devices around is also problematic (when you are already connected to a device).

If you really want to use Wifi-Direct you would probably need to use one WiFiP2P-group and connect all devices to it. This group would act just like a regular network, and all game-room-related stuff would have to be managed by one node acting as a typical server (or maybe not a typical server but some other network solution).

If you don't really need WifiP2P use just a regular Wifi. Connect all devices to one network (maybe even start a hotspot on one of your devices), and whole connection process can be relatively simple, performed in background without user being directly involved in it. Human-readable room names are not a problem, since you can send anything from your server.

Scenario B:

If you answered "Yes" to question 3. and you really need to use WifiP2P, you will need to find some way to broadcast your "human-readable" names to other devices.

You probably think it's super easy: you connect to other device, tell the name of the room you've created, and you're done. Not that simple. As I said before:

obtaining a WifiP2P connection is inseperably linked with displaying a system window (asking if you really want to connect to a device)

So the whole process would be more-less:

  1. Device A: initiate connecting to Device B (this step can be performed by device B as well)

  2. Device B: ugly system window appears asking you if you want to connect to Android-ao12ij219sa (some PROGRAMMATICALLY UNCHANGEABLE system device name)

  3. Device B: accepting

  4. Device B: waiting for connection result

  5. Device B: connected, waiting for information about Device A's room name

  6. Device A: connected, sending room's name

  7. Device B: Device A's room name obtained, disconnecting (future connection request will also result in showing system window)

While steps 1-7 are being performed no other device can connect to Device A (so during that time no other device can obtain room's name).

What could be done:

  1. Use WifiP2P Service Discovery. It allows for broadcasting some information without the need to obtain a connection. Unfortunatelly it's even worse docummented than WifiP2P itself, and it might be even less reliable (subjectively). If you want to make a reliable solution based on that you will need to spend hours of testing and finding different cases in which it might not work. I know from experience that it's possible, but will require from you a number of workarounds to be implemented so it can always obtain a stable WiFiP2P connection.

  2. Send to your devices, a mapping between those (unchangeable) WifiP2P names and created room names, in some other way. For example through your server api or something...

Comments