Multicast Messaging Example Using HydraP2P

Posted on September 7, 2010 | 4 comments

If you are looking for a way to have devices talk to each other with out the devices knowing about each other check out this post. There are various options but in this post I will talk about using Flash Player’s multicast ability. The underlying API for this Flash Player 10.1 feature is NetGroup and RTMFP groups. Basically it allows you to connect to a multicast ip and send messages for any one listening to receive. This is not a direct message to a specific device so beware the messages are broadcast-ed to all devices on the network. You can configure what multicast ip (anything above 241.0.0.1) and the port (make it unique so go high >1024) which lessens the chance for someone to sniffer the packets. For most cases it won’t matter and you could do your own in message logic to lock down your data flow.

Since any multi-user/device application requires a bit of logic to handle users, channels of messages, etc… I choose to try out the HydraP2P library. Dominic Grafen has created a library to abstract out the connecting and handling of users and channels to make multi-user apps a bit more manageable, he has a basic AS3 chat example here. His example uses Stratus service and will work outside of multicasting. What I wanted to do was use the HydraP2P library for just RTMFP multicast and provide an example in Flex 4.

Ok, enough of the introduction lets look at some code. You can grab the source as a Flash Builder 4 fxp project file: MulticastTest.fxp.

The project has two main applications in it. MulticastTest.mxml is example by fellow Adobe Platform Evangelist Tom Krcha. I modified the chat application into the HydraP2PTest.mxml application to use HydraP2P classes.

The first thing to get HydraP2P’s HydraService setup to use multicast is to pass in the multicast service string: “rtmfp:”. When using Stratus you would provide the full Stratus url along with developer API key. But just “rtmfp:” tells the NetConnection to use the local multicast address set in the NetGroup and GroupSpecifier.

Once I have the HydraService configured with the right server string then I need to create a channel, HydraChannel. This channel then gets passed in the GroupSpecifier that is configured for a particular multicast address. Check out the code below:

hydraConn = new HydraService("chattest1", "rtmfp:");
hydraConn.addEventListener(HydraEvent.SERVICE_CONNECT_SUCCESS, serviceHandler);
hydraConn.addEventListener(HydraEvent.SERVICE_CONNECT_CLOSED, serviceHandler);
hydraConn.addEventListener(HydraEvent.SERVICE_CONNECT_FAILED, serviceHandler);

var specifier:GroupSpecifier = new GroupSpecifier("hydrap2ptest/groupOne");
specifier.postingEnabled = true;
specifier.ipMulticastMemberUpdatesEnabled = true;
specifier.addIPMulticastAddress("225.225.0.1:35353");

multicastChatChannel = new HydraChannel(hydraConn, "ch2", specifier, true);
multicastChatChannel.addEventListener(HydraUserEvent.USER_CONNECT, userHandler);
multicastChatChannel.addEventListener(HydraUserEvent.USER_DISCONNECT, userHandler);
multicastChatChannel.addEventListener(HydraEvent.CHANNEL_CONNECT_FAILED, serviceHandler);
multicastChatChannel.addEventListener(HydraEvent.CHANNEL_CONNECT_REJECTED, serviceHandler);
multicastChatChannel.addEventListener(HydraCommandEvent.COMMAND_RECEIVED, commandMessageHandler);
multicastChatChannel.addEventListener(HydraCommandEvent.COMMAND_SENT, commandMessageHandler);

hydraConn.commandFactory.addCommandCreator(new TextCommandCreator());

hydraConn.addChannel(multicastChatChannel);
hydraConn.connect(txtUser.text);

The things you need to know about HydraP2P are that its made up of a service, channels, and typed message commands. The idea is to have the developer create custom commands and command creators to handle parsing of the messaging into typed commands. In my case I created a TextCommand class that exposes a string friendly userName and text property. The HydraService needs to know how to parse incoming messages and this is were the TextCommandCreator comes into play. You’ll see above that I created a instance of the TextCommandCreator and added it to the HydraService.commandFactory. The TextCommandCreator looks like this:

package com.renaun.hydrap2p
{
import org.devboy.hydra.commands.IHydraCommand;
import org.devboy.hydra.commands.IHydraCommandCreator;

/**
 * @author Renaun Erickson - renaun.com
 */

public class TextCommandCreator implements IHydraCommandCreator
{
    public function createCommand(type:String, timestamp:uint, userId:String,
                                  senderPeerId:String, info:Object):IHydraCommand
    {
        if (type != commandType)
            throw new Error("CommandTypes do not match!");
       
        var command : TextCommand = new TextCommand();
        command.userName = info.userName;
        command.text = info.text;
        command.userId = userId;
        command.senderPeerId = senderPeerId;
        return command;
    }

    public function get commandType():String
    {
        return TextCommand.TYPE;
    }
}
}

With typed commands now in the message handling event I can know exactly what commands I want to handle for what application logic. Here is my message handler method in the HydraP2PTest application:

public function commandMessageHandler(event:HydraCommandEvent):void
{
    if (event.command.type == TextCommand.TYPE)
    {
        var command:TextCommand = event.command as TextCommand;
        output(command.userName+": "+command.text);
    }
}

Thats basically all the setup to use HydraP2P library. All those event listeners are what drive the application to change connected and disconnected state, notify of users joining/leaving, and posting chat messages. Check out the source code and have fun with it.

NOTE: I created my own TextCommand, as I wanted to know how things work, but if you look at HydraP2P it does come with some basic chat classes to get you up and running.

  • Pingback: Swf.hu 2.0 – flash és webfejlesztés » Heti link gy?jtemény

  • http://www.psyked.co.uk/ James

    This example sounds great – is the Flex 4.5 SDK a requirement for building this though, or can we use the Flex 4.1 SDK?

    • http://www.renaun.com Renaun Erickson

      The only requirement is to have your AS3 or Flex based app target Flash Player 10.1. The HydraP2P library is all AS3 and relys on Flash Player 10.1 features.

  • Mariovde

    This works great. Thanks!
    I wanted to change the ip to 127.0.0.1 and test it: works! So I am not bound to any changes in the network. So this works beautifully on XP
    But: build as 2 seperate AIR apps, with ip 127.0.0.1, installing it on Win7, they can’t connect. Install it on XP: works like a charm… Any ideas?

    • David

      firewall setting on win7 machine?