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:
- The SocketServerDiscoveryClient broadcasts a message (data is a static ID to avoid interference with other services) over UDP into the network.
- 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.
- 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.
- 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.
- After instantiation of the DiscoveryServer we start it, which makes it asynchonously listen in the background, by calling start().
Using java Syntax Highlighting
- private void initDiscoveryServer() throws Throwable {
- final byte[] serverIPAddress = WifiUtils.getWifiIPv4AddressRaw(this);
- this.mSocketServerDiscoveryServer = new SocketServerDiscoveryServer<DefaultDiscoveryData>(
- new ExampleSocketServerDiscoveryServerListener()) {
- @Override
- protected DefaultDiscoveryData onCreateDiscoveryResponse() {
- return new DefaultDiscoveryData(serverIPAddress, SERVER_PORT);
- }
- };
- this.mSocketServerDiscoveryServer.start();
- }
Parsed in 0.011 seconds, using GeSHi 1.0.8.4
This is what needs to be done on the client side.
- At first, we need to determine a broadcastIPAddress, by calling the getBroadcastIPAddressRaw utility function in WifiUtils.
- 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.
- After instantiation, we can call discoverAsync to initiate discovery attempts, which will be executed in serial.
Using java Syntax Highlighting
- private void initDiscoveryClient() throws Throwable {
- final byte[] broadcastIPAddress = WifiUtils.getBroadcastIPAddressRaw(this);
- this.mSocketServerDiscoveryClient = new SocketServerDiscoveryClient<DefaultDiscoveryData>(
- broadcastIPAddress,
- DefaultDiscoveryData.class,
- new ISocketServerDiscoveryClientListener<DefaultDiscoveryData>() {
- @Override
- public void onDiscovery(final SocketServerDiscoveryClient<DefaultDiscoveryData> pSocketServerDiscoveryClient, final DefaultDiscoveryData pDiscoveryData) {
- initActualClient(pDiscoveryData.getServerIP(), pDiscoveryData.getServerPort());
- }
- /* There are two more callbacks for timeouts/exceptions. */
- });
- this.mSocketServerDiscoveryClient.discoverAsync();
- }
Parsed in 0.011 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