MultiPlayerExtension - AutoDiscovery

  ... information about changes and new features of AndEngine,

MultiPlayerExtension - AutoDiscovery

Postby Nicolas Gramlich » Fri Jun 24, 2011 2:08 am

Hello Community,

autodiscovery.png
autodiscovery.png (11.58 KiB) Viewed 4221 times


the last days I've been implementing autodiscovery for the AndEngineMultiplayerExtension, which will allow you to have "zeroconfiguration" multiplayer setup (over WiFi/local network), what basically means that the users won't have to enter the IP of the server anymore. What you could do too is a little server browser for situations where there would be more than one server available.

Basically it is a small, extensible protocol that handles the exchange of the server ip and port using UDP from the server to the clients. This is how it works:

  1. The SocketServerDiscoveryClient broadcasts a message (data is a static ID to avoid interference with other services) over UDP into the network.
  2. The SocketServerDiscoveryServer will catch that message, checks if the data is the expected static ID, and respond with an DiscoveryData that get serialized and sent to the SocketServerDiscoveryClient.
  3. The SocketServerDiscoveryClient receives and deserializes the DiscoveryData and can establish a connection to the actual SocketServer using the information contained in the DiscoveryData.

So in the end what happend is that the SocketServerDiscoveryServer sends a DiscoveryData object to the SocketServerDiscoveryClient.

Following is an actual implementation.

This is what needs to be done on the server side.
  1. Basically we create a DiscoveryServer and make it listen to a default port.
    • When the DiscoveryServer is being discovered, we tell him what data to send to the client in onCreateDiscoveryResponse (you can use any class that implements IDiscoveryData, but for simplicity I'm using DefaultDiscoveryData here, which holds "only" an IP and a Port).
    • The ExampleSocketServerDiscoveryServerListener will simply send all callbacks to LogCat.
  2. After instantiation of the DiscoveryServer we start it, which makes it asynchonously listen in the background, by calling start().
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. private void initDiscoveryServer() throws Throwable {
  2.   final byte[] serverIPAddress = WifiUtils.getWifiIPv4AddressRaw(this);
  3.  
  4.   this.mSocketServerDiscoveryServer = new SocketServerDiscoveryServer<DefaultDiscoveryData>(
  5.     new ExampleSocketServerDiscoveryServerListener()) {
  6.     @Override
  7.     protected DefaultDiscoveryData onCreateDiscoveryResponse() {
  8.       return new DefaultDiscoveryData(serverIPAddress, SERVER_PORT);
  9.     }
  10.   };
  11.  
  12.   this.mSocketServerDiscoveryServer.start();
  13. }
Parsed in 0.033 seconds, using GeSHi 1.0.8.4


This is what needs to be done on the client side.
  1. At first, we need to determine a broadcastIPAddress, by calling the getBroadcastIPAddressRaw utility function in WifiUtils.
  2. Now we instantiate a DiscoveryClient.
    • The second parameter is the class of the DiscoveryData we are exchaning between the DiscoveryServer and the DiscoveryClient. This needs to be the same class that the DiscoveryServer returns in onCreateDiscoveryResponse.
    • The third parameter is a listener that will called its onDiscovery when a discovery was successful.
      • Et voila, it has the DiscoveryData that the server created as a parameter.
  3. After instantiation, we can call discoverAsync to initiate discovery attempts, which will be executed in serial.
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. private void initDiscoveryClient() throws Throwable {
  2.   final byte[] broadcastIPAddress = WifiUtils.getBroadcastIPAddressRaw(this);
  3.  
  4.   this.mSocketServerDiscoveryClient = new SocketServerDiscoveryClient<DefaultDiscoveryData>(
  5.       broadcastIPAddress,
  6.       DefaultDiscoveryData.class,
  7.       new ISocketServerDiscoveryClientListener<DefaultDiscoveryData>() {
  8.         @Override
  9.         public void onDiscovery(final SocketServerDiscoveryClient<DefaultDiscoveryData> pSocketServerDiscoveryClient, final DefaultDiscoveryData pDiscoveryData) {
  10.           initActualClient(pDiscoveryData.getServerIP(), pDiscoveryData.getServerPort());
  11.         }
  12.    /* There are two more callbacks for timeouts/exceptions.  */
  13.   });
  14.  
  15.   this.mSocketServerDiscoveryClient.discoverAsync();
  16. }
Parsed in 0.033 seconds, using GeSHi 1.0.8.4


Note: Don't forget to terminate all Clients/Servers in onDestroy of the Activity!

That's it.

For a full, working example have a look at the new MultiplayerServerDiscoveryExample.

Best Regards,
Nicolas
Nicolas Gramlich
Site Admin
 
Posts: 1734
Joined: Mon Jun 07, 2010 6:20 pm
Location: Schriesheim, Germany

Re: MultiPlayerExtension - AutoDiscovery

Postby coder_t2 » Fri Jun 24, 2011 4:09 am

Sounds awesome
coder_t2
 
Posts: 27
Joined: Wed Jun 01, 2011 11:40 pm

Re: MultiPlayerExtension - AutoDiscovery

Postby Nicolas Gramlich » Sun Jun 26, 2011 11:14 pm

*Updated* :)

Note I actually have this working in my new game and it kicks ass :!:
Nicolas Gramlich
Site Admin
 
Posts: 1734
Joined: Mon Jun 07, 2010 6:20 pm
Location: Schriesheim, Germany

Re: MultiPlayerExtension - AutoDiscovery

Postby Nicolas Gramlich » Mon Jun 27, 2011 2:13 pm

I just made a little animation for this:
autodiscovery.png
autodiscovery.png (11.58 KiB) Viewed 4221 times
:D
Nicolas Gramlich
Site Admin
 
Posts: 1734
Joined: Mon Jun 07, 2010 6:20 pm
Location: Schriesheim, Germany

Re: MultiPlayerExtension - AutoDiscovery

Postby flyMASTER » Sun Jul 03, 2011 8:48 pm

That's a very nice feature :) Thx!
In some WLAN home networks I get immediate SocketTimeoutExceptions on the client side. Do I have to forward some ports inside a home network? It always works fine on mobile hotspots...
flyMASTER
 
Posts: 7
Joined: Wed May 25, 2011 2:08 pm
Location: Berlin

Re: MultiPlayerExtension - AutoDiscovery

Postby Nicolas Gramlich » Mon Jul 04, 2011 1:09 pm

Hi,

sounds like your router blocks the broadcast :(

Best Regards,
Nicolas
Nicolas Gramlich
Site Admin
 
Posts: 1734
Joined: Mon Jun 07, 2010 6:20 pm
Location: Schriesheim, Germany

Re: MultiPlayerExtension - AutoDiscovery

Postby EddieH » Sun Aug 07, 2011 8:56 pm

I want to make an asynchronous turn based multiplayer game similar to what words with friends do, meaning people can play 10+ games at a time, and players can open their app whenever to check if their opponents finished their turn. Any ideas if this is possible, and/or where I should start? should I use google appengine or something else?
EddieH
 
Posts: 48
Joined: Sun Jan 30, 2011 4:34 am


Return to Updates

Who is online

Users browsing this forum: ApkAndroid and 2 guests