P2P – Share real-time data across Android and desktop AIR applications to build multiuser games and collaborative RIA

Using native IP-only multicast feature available with Adobe AIR 2.0 and Flash Player 10.1 you can easly establish a connection and share real-time data between two or more clients over the same network (LAN).

The immediate advantage you can get from this tecnique is that you won’t need to use a dedicated server (like Flash Media Server, AFCS, and so on) to share real-time data across multiple clients.

Another cool stuff is that you can use P2P to share data between mobile Air for Android apps and desktop AIR applications, and in this post I’ll provide you a video demo and the source code to put in place this, getting you the fundamentals to build your own multiuser game or collaborative application.

androidp2p_screenshotvideo

What you can also do using this technology:

- Building real-time chats
- Collaborative whiteboards
- real-time multiusers games
- manage a desktop AIR application from your Android device: let’s think about an AIR Media Center on your TV managed from your mobile device; or moving a slide presentation on your laptop from your Android smartphone, and so on
- everything else needs to share real-time data across multiple clients and different platforms.

Below, the video demo (no-sound) where I show you the final result.
Moving the movieclip on my Android device, I will move the clip on my desktop application too, and viceversa.

Following the ActionScript source code (full-commented) to build the Air for Android application in Adobe Flash Professional CS5.

Document class:

package  {
 
	import flash.display.MovieClip;
	import flash.events.NetStatusEvent;
	import flash.events.MouseEvent;
	import flash.net.NetConnection;
	import flash.net.NetGroup;
	import flash.net.GroupSpecifier;
	import fl.transitions.Tween;
	import fl.transitions.easing.Strong;
 
 
	public class Main extends MovieClip {
 
		private var nc:NetConnection;
		private var group:NetGroup;
 
 
		/**
		 * Constructor
		 */
		public function Main()
		{
 
			mc.addEventListener(MouseEvent.MOUSE_DOWN, drag);
			this.stage.addEventListener(MouseEvent.MOUSE_UP, drop);
 
			connect();
		}
 
 
		/**
		 * Connect
		 */
		private function connect():void
		{
			nc = new NetConnection();
			nc.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
			nc.connect("rtmfp:");
		}
 
 
		/**
		 * Net Status event handler
		 */
		private function netStatus(event:NetStatusEvent):void{
 
			switch(event.info.code){
 
				// The connection attempt succeeded
				case "NetConnection.Connect.Success":
					setupGroup();
					break;
 
				// The NetGroup is successfully constructed and authorized to function.
				case "NetGroup.Connect.Success":
					// Do nothing
					break;
 
				// A new group posting is received
				case "NetGroup.Posting.Notify":
					moveObject(event.info.message);
					break;
			}
		}
 
 
		/**
		 * Create a group
		 */
		private function setupGroup():void
		{
			// Create a new Group Specifier object
			var groupspec:GroupSpecifier = new GroupSpecifier("myGroup/groupA");
 
			// Enable posting
			groupspec.postingEnabled = true;
 
			// Specifies whether information about group membership can be exchanged on IP multicast sockets
			groupspec.ipMulticastMemberUpdatesEnabled = true;
 
			// Causes the associated NetStream or NetGroup to join the specified IP multicast group and listen to the specified UDP port.
			groupspec.addIPMulticastAddress("225.225.0.1:30000");
 
			// Constructs a NetGroup on the specified NetConnection object and joins it to the group specified by groupspec.
			group = new NetGroup(nc,groupspec.groupspecWithAuthorizations());
 
			// Set the NET_STATUS event listener
			group.addEventListener(NetStatusEvent.NET_STATUS,netStatus);
		}
 
 
 
		/**
		 * Drag the object
		 */
		protected function drag(e:MouseEvent):void
		{
			this.stage.addEventListener(MouseEvent.MOUSE_MOVE, move);
		}
 
 
		/**
		 * Move the object in accordind of the mouse position
		 */
		protected function move(e:MouseEvent):void
		{
			mc.x = this.mouseX - mc.width/2;
			mc.y = this.mouseY - mc.height/2;
			e.updateAfterEvent();
		}
 
 
		/**
		 * Drop the object and send a message to all members of a group.
		 */
		protected function drop(e:MouseEvent):void
		{
 
			// Create the object to send to all members
			var obj:Object = new Object();
 
			// Save the current movieclip position
			obj.x = mc.x ;
			obj.y = mc.y ;
 
			// Set the peerID to a group address suitable for use with the sendToNearest() method.
			obj.sender = group.convertPeerIDToGroupAddress(nc.nearID);
 
			// Sends a message to all members of a group.
			group.post(obj);
 
			// REmove the move event listener
			this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, move);
		}
 
 
 
		/**
		 * Move the object after posting has been received
		 */
		public function moveObject(message:Object):void
		{
			var myTweenX:Tween = new Tween(mc, "x", Strong.easeInOut, mc.x, message.x, 1, true);
			var myTweenY:Tween = new Tween(mc, "y", Strong.easeInOut, mc.y, message.y, 1, true);
		}
 
 
	}
}

To test this sample you should use the previous class as document class of a new Air for Android Flash file (using Flash Professional CS5) and create a movieclip on your stage setting its instance name to ‘mc’ (see image below):

androidp2p_fla

To verify if P2P is working, let’s run two instances of the application on your desktop and drag the movieclips.
If it works, install the application on your Android device, open an instance on your desktop and move the movieclip on both platforms to see if clients are connected.

Remember to set the android manifest permission to allow internet connections on your android xml-descriptor file:

  <android>
    <manifestAdditions>
       <![CDATA[
<manifest>
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>]]>
    </manifestAdditions>
  </android>

-
Download the source code and the APK installation file for Android


Related articles from flashrealtime.com
I got inspiration from flashrealtime.com blog and I suggest you to read and watch following tutorials:
- Building P2P Multiplayer Games at Adobe MAX 2010 (interesting video)
- Local Flash Peer-to-Peer Communication over LAN (without Cirrus/Stratus)
- Flash gets GPU-accelerated 3D! MAX Racer with P2P multiplayer

Comments (17)

  1. Pingback: Drupal Development India - Wordpress 201

  2. Pingback: Flash Tutorial: How to use P2P to share data between mobile Air for Android apps and desktop AIR applications | Adobe Flash Lite

  3. Helge Betzinger (reply)

    November 27, 2010 at 7:30 pm

    Nice, but where is the long latency is coming from?

    1. Fabio Biondi (reply)

      November 28, 2010 at 2:06 pm

      @Helge: if you try to sync every single point (x,y) you won’t obtain a fluid movement in the receiver client, so I have used tweens to create smooth transitions.
      This is a Tom Krcha’s trick (from FlashRealTime.com) that suggest to use interpolation in the receiver client. See the FlashRealTime links to get more info about it.

  4. iBrent (reply)

    November 28, 2010 at 12:15 am

    Awesome tutorial! This is by far one of the coolest features that hardly gets mentioned when discussing Flash Player 10.1 and AIR 2. I was blown away by some of the demos shown at MAX this year.

    iBrent

  5. stef (reply)

    December 2, 2010 at 10:45 am

    Adding interpolations won’t reduce the latency. This is just a trick, and a dirty one… User experience won’t be better.

  6. Fabio Biondi (reply)

    December 2, 2010 at 11:13 am

    @stef: yes it’s a trick but i’m not agree with you.
    You can’t avoid the latency, so this is good way to provide a good UX in games and many apps.
    Naturally you can find other ways… this is just a sample using Tween (that it’s not the best and fast solution).

  7. Diether (reply)

    January 17, 2011 at 6:12 pm

    Congrat’s Fabio.
    Only one question. Everytime when i execute the swf, my firewall is activated and asks me if I want to authorize to run the application. is there any way my swf not get blocked by windows firewall?

  8. azhar (reply)

    March 24, 2011 at 5:11 am

    hi. I have tried following the steps you have proposed. It works well between 2 swf files but not when I tried on my mobile. Have I missed out any important steps? I do hope to hear from you soon.

    1. Fabio Biondi (reply)

      March 24, 2011 at 11:13 am

      Did you set the INTERNET permission when publishing the apk file?

  9. Tan (reply)

    March 28, 2011 at 8:22 am

    Hi there,

    Really nice article showcasing the p2p capabilities with AIR for Android. I am trying to create an application to use this method to control the power point slides in my PC but I am not sure how to start.Do I need to convert the .ppt slides into a .swf file?And how do i actually program to move from one slide to another? Any advice would be appreciated. Thanks!

    Regards

  10. Stephen (reply)

    May 26, 2011 at 2:58 pm

    Works perfectly with packager for iOS too.

  11. Geo (reply)

    December 21, 2011 at 1:04 pm

    Hi Fabio,

    Thanks for the nice article.

    Can you please explain me how you are setting up a Peer-to-peer connection between your android mobile and the Laptop? Are you using the USB or WiFi Tethering? If we use WiFi Tethering in Android 2.2, will this application work? I’m trying to use this method, but was not successful. :(

    Thanks,
    Geo

  12. Peter J. (reply)

    June 8, 2012 at 9:07 am

    I would need application for multi reading lessons in libarary with Samsung TAB (4.0.3)…

    I would like to have a source folder in my TAB where I put in txt files or pdf or anything else…
    Also during reading I would like to have an option to search betwen them and people don’t see my serching – they just see which will be next text or file at the bottom (like a play list) with changing possibility (for master only).

    Can someone send me an email how to do that or soucre how this would look like???

    This source is realy great if you know what to do :(
    I’m totally new in development and an sample project would also be great!

    Thanks!
    Peter
    djpero@gmail.com

  13. Kenny (reply)

    September 13, 2013 at 2:49 pm

    Hi fabio,

    your tutorial is awesome, it works well with 2 swf in one computer, but when I try using on android, I can’t make it sync at all. I already publish my package with internet connection checked. Can you show me how you establish your p2p connection. I’m connecting both in the same router. Thank you

Leave a Reply

Your email address will not be published. Required fields are marked *

Published on: 23 November 2010
Posted by:
Discussion: 17 Comments