PatrickBay.ca

This time, it's personal.

I want to jump right into this topic because it’s neat and interesting and fun, but there are a couple of things we need to set up first.

Sorry.

But I promise it’s not going to kill you.

Step 1 of 3 — get yourself a RTMFP rendezvous server. Absolute must unless you’re only communicating over a LAN or Wireless LAN (then it just works by magic).

Some options:

  1. If you prefer free and in control, grab the open source Windows command-line version of OpenRTMFP/Cumulus http://jazzmatazz.free.fr/Cumulus/CumulusServer.zip
  2. If you’re feeling adventurous, you can also compile the C++ source code for your own setup:  https://github.com/OpenRTMFP/Cumulus
  3. If you’re not willing to muck around with a command prompt or a compiler, sign up for a free Cirrus / rtmfp.net account at:https://www.adobe.com/cfusion/entitlement/index.cfm?e=cirrus
  4. If you’re able and willing to plunk down a cool wad, go with Adobe’s Media thingie: http://www.adobe.com/ca/products/adobe-media-server-family.html

Step 2 of 3 — grab a copy of SwAG and have a quick look at how SwAG events work; the P2P stuff uses these kinds of events to communicate, so it’ll come in handy.

Step 3 of 3 – now the good stuff — write your application!

SwAG’s most important class is swag.network.SwagCloud. I chose the name because it sounds nice and fluffy and amorphous. A SwagCloud is an enhanced, self-managing NetGroup, if you want to get technical (but you don’t need to).

Creating a SwagCloud is as simple as creating an instance, adding a listener to it, and then launching the new connection on its way.

Here’s a shortened version of how that might look in real life…first we declare some variables (or you can always hard-code these if you like):

private var _RTMFPServerAddress:String="rtmfp://p2p.rtmfp.net/"; //Or rtmfp://127.0.0.1/ if running Cumulus locally
private var _developerKey:String="SOMEVALUE"; //Get this via the Cirrus sign-up process; ignore (or set to empty) if using Cumulus
private var _group:SwagCloud=null;
private var _groupName:String="MyTotallyUniqueGroupName123";
private var _groupPassword:String="Members0nly!";
private var _groupHash:String="E><tr4$3curity";

…then we set up a few useful listeners and start up our group:

SwagDispatcher.addEventListener(SwagCloudEvent.GROUPCONNECT, this.onConnect, this, this._group);
SwagDispatcher.addEventListener(SwagCloudEvent.BROADCAST, this.onBroadcast, this, this._group);
SwagDispatcher.addEventListener(SwagCloudEvent.DIRECT, this.onDirectMessage, this, this._group);
this._group=new SwagCloud(this._RTMFPServerAddress, this._developerKey);
this._group.connectGroup(this._groupName, true, this._groupPassword, this._groupHash, false);

…and then we define the listeners to do some stuff we want:

public function onConnect(eventObj:SwagCloudEvent):void {
 trace ("We're connected to the group.");
 ...
public function onBroadcast(eventObj:SwagCloudEvent):void {
 trace (eventObj.remotePeerId+" broadcast this to the group: "+eventObj.data);
 ...
public function onDirectMessage(eventObj:SwagCloudEvent):void {
 trace (eventObj.remotePeerId+" sent this directly to me: "+eventObj.data);
 ...

…and that’s it.

As I mentioned earlier, if you wanted to hard-code variables right into the functions, you could shorten this example by a third. And if you only wanted to create a “beacon” type of app that didn’t need to listen to broadcasts or direct messages, you could further cut the example by another two-thirds.

If you store peer IDs when they connect to the group (another event you can listen to), sending an encrypted message directly to a peer is as easy as:

var someData:Object=new Object();
someData.message="Hello there!";
this._group.send(someData, peerID);

…and broadcasting to all peers even easier:

var someData:Object=new Object();
someData.message="Hello there!";
this._group.broadcast(someData);

You don’t need to create an object for the data, I just do that for extensibility. The following is also perfectly valid:

var someData:String="Hello there!";
this._group.broadcast(someData);

…or even:

this._group.broadcast("Hello there!");

“But hang on, Patrick,” you say astutely,” isn’t this just an overlay on top of the built-in RTMFP networking?”

Yup, that’s pretty much exactly what it is. It doesn’t do anything that RTMFP don’t does, it just simplifies things a lot.

Just have a look at the guts of SwagCloud to see what I mean. A from-scratch NetGroup connection, for example, is a two-step process; this is handled in SwAG and simplified to one step. Even something as seemingly trivial as streaming peer-to-peer audio via a NetStream.publish call is likely to encounter a microphone security dialog — handled by SwAG. Plus, SwagCloud takes care of converting native data types for transmission (I’ve even successfully transferred prototype MovieClip instances extracted from running code, believe it or not), so you may get some useful info out of it even if you’re already RTMFP-experienced.

In other words, if you haven’t worked much with RTMFP and/or want to skip the hassle of getting it up and running (i.e. you’d rather focus on doing something with it), I’d recommend having a look at SwAG’s SwagCloud class as well as its supporting classes like SwagCloudData, SwagCloudShare, and SwagCloudEvent.

So what exactly can you do with RTMFP and, by extension, with SwAG?

  • Any type of low-latency, peer-to-peer chat or gaming application one could care to imagine.
  • A one-to-many video or audio (or both) broadcasting system. The RTMFP server only takes care of connecting peers to each other, the streams are then distributed and multiplied peer to peer. If you host the RTMFP server on the same computer or device, you can stream to many thousands directly — no third-party needed. Read more about how this works in SocialCastr.
  • A distributed file sharing service. Despite the contrary claims that Adobe makes on the subject, SwAG has an entire class that proves that this is very possible. Adobe doesn’t make it super easy to use though, hence SwAG.
  • A distributed computing platform. Distributing a module designed to run concurrent calculations (Bitcoin mining, for example), is simply a matter of sharing the “workhorse” SWF with your peer group (SwagCloud instance), and having them run it with some custom startup parameters. Or that module could be part of a more static, custom-built application; that’s a perfectly valid approach too, albeit not as flexible in the long run.
  • An overlay network. If enough peers participate in it, many of the above features could be combined into a very robust overlay network that could have many of the features of something like Tor. Or BitTorrent. Or Hulu. Or maybe with the assistance of dedicated peers, a new type of content delivery network.

The (personally tested) possibilities of RTMFP are tough to shrug off, but at the same time they seem somewhat secondary to Adobe who seem content to leave some of the detailed implementation questions to developers. For example, object replication (peer-to-peer data sharing) is still somewhat of a black art, and even something as basic as a NetGroup connection event is not well-advertised as actually coming from the NetConnection object. So as I mentioned earlier, even if you don’t end up using SwagCloud, hopefully you’ll be able to use what I learned in what was often good old-fashioned trial-and-error to build your exciting new p2p products.

August 13th, 2014

Posted In: Development / Coding

Tags: , , , , , ,

Leave a Reply

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