For a variety of reasons, you may need to communicate between two Flash Player instances. You may do this to implement debug logging, communicate with a mini game, or coordinate between a main SWF and an advertisement SWF. So, what kind of speed can you expect? This article will show you.

The preferred way of communicating between two Flash Player instances is to use the LocalConnection class. It allows you to easily listen for and send data. Adobe’s documentation on it is pretty good and is a good place to learn the basics. My test uses those basics to construct two applications– Sender and Receiver— that talk to each other. Each has a LocalConnection to send on and a LocalConnection to receive on. Receiver is the simpler of the two:

package
{
	import flash.display.*;
	import flash.text.*;
	import flash.net.*;
 
	/**
	*   An app to receive messages from another app
	*   @author Jackson Dunstan
	*/
	public class Receiver extends Sprite
	{
		private var __logger:TextField;
		private var __sendLC:LocalConnection;
		private var __receiveLC:LocalConnection;
 
		public function Receiver()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			__logger = new TextField();
			__logger.autoSize = TextFieldAutoSize.LEFT;
			__logger.text = "I am the Receiver\n";
			addChild(__logger);
 
			__sendLC = new LocalConnection();
 
			__receiveLC = new LocalConnection();
			__receiveLC.client = this;
			try
			{
				__receiveLC.connect("receiver");
			}
			catch (err:Error)
			{
				__logger.appendText("Couldn't connect: " + err + "\n");
			}
		}
 
		public function receiveLC(): void
		{
			__sendLC.send("sender", "respondLC");
			__logger.text = "Message receieved at " + (new Date());
		}
	}
}

As you see, Receiver just listens for a LocalConnection message and responds to it immediately. It’s basically a ping responder. Sender isn’t much more complicated:

package
{
	import flash.display.*;
	import flash.text.*;
	import flash.net.*;
	import flash.events.*;
	import flash.utils.*;
 
	/**
	*   An app to send messages to another app
	*   @author Jackson Dunstan
	*/
	public class Sender extends Sprite
	{
		private var __logger:TextField;
		private var __sendLC:LocalConnection;
		private var __receiveLC:LocalConnection;
		private var __sendTime:int;
		private var __totalTime:int;
		private var __totalRoundtrips:int;
		private var __started:Boolean;
 
		public function Sender()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			__logger = new TextField();
			__logger.autoSize = TextFieldAutoSize.LEFT;
			__logger.text = "I am the Sender\n";
			addChild(__logger);
 
			__sendLC = new LocalConnection();
			__receiveLC = new LocalConnection();
			__receiveLC.client = this;
			try
			{
				__receiveLC.connect("sender");
			}
			catch (err:Error)
			{
				__logger.appendText("Couldn't connect: " + err + "\n");
			}
 
			var tf:TextField = new TextField();
			tf.selectable = false;
			tf.mouseEnabled = false;
			tf.autoSize = TextFieldAutoSize.LEFT;
			tf.x = 5;
			tf.y = 5;
			tf.text = "Start";
 
			var spr:Sprite = new Sprite();
			spr.addChild(tf);
			spr.graphics.beginFill(0xffffff);
			spr.graphics.drawRect(0, 0, tf.width+10, tf.height+10);
			spr.graphics.endFill();
			spr.addEventListener(MouseEvent.CLICK, onStart);
			spr.x = 500;
			spr.y = 5;
			spr.buttonMode = true;
			spr.useHandCursor = true;
			addChild(spr);
		}
 
		private function onStart(ev:Event): void
		{
			__started = true;
			removeChild(ev.target as DisplayObject);
			send();
		}
 
		private function send(): void
		{
			__sendTime = getTimer();
			try
			{
				__sendLC.send("receiver", "receiveLC");
			}
			catch (err:Error)
			{
				__logger.text = "Send error: " + err;
			}
		}
 
		public function respondLC(): void
		{
			if (!__started)
			{
				return;
			}
			var dTime:int = getTimer()-__sendTime;
			__totalTime += dTime;
			__totalRoundtrips++;
			var average:Number = Number(__totalTime) / __totalRoundtrips;
			__logger.text = "Time: " + dTime + ". Average: " + average.toFixed(2);
			send();
		}
	}
}

Besides implementing a button to kick things off, Sender records and displays the time it took for a message to be sent and received: the so-called “roundtrip” time. Sender keeps sending forever so you’ll be able to observe the average time settle down after a few seconds. Here’s what it settled down to for me:

Environment Average Roundrip Time
2.2 Ghz Intel Core 2 Duo, 2 GB RAM, Mac OS X 10.6 18.0

Since the roundtrip time includes two LocalConnection messages, we can assume that each message only takes half of the roundtrip time. To me, I think this is a very reasonable time. It’s certainly good enough to send every frame of an animation, game, video, or other real-time application. However, you should probably limit it to that and not send tons of messages each frame; you’re not likely to find many other single actions that are so expensive! Lastly, here’s a little HTML to bind the Sender and Receiver apps together if you want to run them on the same page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
	<head>
		<title>Flash Comm</title>
	</head>
	<body>
		<div>
			<object type="application/x-shockwave-flash" data="Sender.swf" width="600" height="50">
				<param name="movie" value="Sender.swf" />
			</object>
			<br/>
			<object type="application/x-shockwave-flash" data="Receiver.swf" width="600" height="50">
				<param name="movie" value="Receiver.swf" />
			</object>
		</div>
	</body>
</html>