Flash-Network Developer Guide

Flash Network is a set of library and application to allow building any type of network applications running in the browser. It defines extensive Javascript API for various network socket feature such as DNS resolution, client and server TCP socket, generic UDP socket and real-time RTP/RTCP socket. It uses Flash Player and Adobe Integrated Runtime (AIR) to facilitate seamless integration with your web application. The idea is to allow any type of network application including multimedia communication application from your web page.

This document gives a quick start for developers to start using the Flash Network project. For end-user's guide, please refer to the user guide. The space on the top-right of this page shows the Flash Network status and any end-user prompts as needed.
  1. How to embed Flash Network in your web page?
  2. How to get local network address and detect change?
  3. How to do DNS resolution?
  4. How to use outbound TCP (stream) socket?
  5. How to use listening TCP (stream) socket?
  6. How to use UDP (datagram) socket?
  7. How to use RTP/RTCP (real-time) socket?
  8. How to attach media (audio/video) to real-time socket?
  9. What are the licensing terms?
Additional documentation.
  1. How to run the supporting application on an external machine?

Alternative content

Get Adobe Flash player

1. How to embed Flash Network in your web page?

Embed: Download the client side files. Include all the necessary javascript libraries in the head part of your HTML page. The flash-network.js file is required and others are dependencies.
  <script type="text/javascript" src="swfobject.js"></script>
  <script type="text/javascript" src="json2.js"></script>
  <script type="text/javascript" src="base64.js"></script>
  <script type="text/javascript" src="flash-network.js"></script>

Embed the Flash Network client SWF in the head part of your HTML page. Tell the Flash Network library about the SWF name which is "flash-network".
  <script type="text/javascript">
    swfobject.embedSWF("NetworkIO.swf", "flash-network", "215", "138", "10.0.0", "expressInstall.swf", {}, 
      {"allowScriptAccess": "always", "flashVars": "apiVersion=1.0&prefix=network.", "bgcolor" : "#ffffff"}, 
      {"id": "flash-network", "name": "flash-network"});
    network.movieName = "flash-network";
  </script>
You need to supply a div identifier, say "flash-network" where the SWF will be loaded.
  <div id="flash-network">
    <h2>Alternative content</h2>
    <p><a href="http://www.adobe.com/go/getflashplayer"><img
    src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif"
    alt="Get Adobe Flash player" /></a></p>
  </div>

The Flash Network library can inform you about the status of the connection with the application. You can set the onstatus function to your callback.
  function statusChanged(status) {
    if (status == "connected") {
      // start your use of Flash Network API
    }
  }
  network.onstatus = statusChanged;

2. How to get local network address and detect change?

The Flash Network library can inform you about the network change event. You can set the onnetworkchange function to your callback. The interfaces property contains an array of network interfaces detected on your system and is updated before the onnetworkchange callback is invoked.
  function networkChanged() {
    /* network.interfaces= */
  }
  
  network.onnetworkchange = networkChanged;
You can click on to see the current list of interfaces. Then change your network, e.g., disable WiFi or Ethernet, and re-enable, to see the changes.

Each item in the interfaces array is an object with these attributes:
activewhether the interface is active or not?
namethe unique name of the interface.
addressesan array of IP addresses. Each address item is an object with these attributes:
ipVersioneither "IPv4" or "IPv6".
addressthe IP address on this interface for this IP version.
broadcastthe broadcast address on this interface for this IP version.
prefixLengththe network mask's prefix length.
hardwareAddressthe hardware or MAC address.
displayNamea displayable name if available.
mtuthe value of MTU in bytes.
parentany parent interface name if applicable.
subInterfacesarray of child interface names if applicable.

In general, you will use the following code to get a valid IPv4 address.
  var address = null;
  for (var i=0; i<network.interfaces.length; ++i) {
    var intf = network.interfaces[i];
    if (intf.active) {
      for (var j=0; j<intf.addresses.length; ++j) {
        var addr = intf.addresses[j];
        if (addr.ipVersion == "IPv4") {
          address = addr.address // store the value 
          break;
        }
      }
    }
    if (address != null) break;
  }
Click on to detect your valid IP address above.

3. How to do DNS resolution?

DNSResolver: The DNSResolver class is used to resolve a host name to IP address or other names using DNS. It supports record types of "A", "AAAA", "MX", "PTR" and "SRV". Click on the run buttons next to the following examples to run that text.

  var d1 = new network.Socket();
  d1.addEventListener("lookup", function(event) { /* result  */ });
  d1.addEventListener("error", function(event) { /* error  */ });
A-record:
Each item in the lookup event's resourceRecrods list has an "address" attribute containing IPv4 address.
  d1.lookup("www.google.com", "A");
AAAA-record:
Each item in the lookup event's resourceRecrods list has an "address" attribute containing IPv6 address.
  d1.lookup("www.cs.columbia.edu", "AAAA");
MX-record:
Each item in the lookup event's resourceRecrods list has an "exchange" attribute containing mail exchange host name. You need to do another DNS lookup to resolve this host name to IPv4 address.
  d1.lookup("www.cs.columbia.edu", "MX");
PTR-record:
Each item in the lookup event's resourceRecrods list has an "ptrdName" attribute containing the pointed host name in reverse lookup.
  d1.lookup("128.59.48.24", "PTR");
SRV-record:
Each item in the lookup event's resourceRecrods list has an "target" attribute containing target host name. You need to do another DNS lookup to resolve this host name to IPv4 address.
  d1.lookup("_sip._udp._iptel.org", "SRV");
Error:
When DNS resolution fails you get the error event.
  d1.lookup("non-existent.something.com", "A");
The DNS resolution is epecially useful for DatagramSocket class which requires an IP address and does not work with host names.

4. How to use outbound TCP (stream) socket?

Socket: The Socket class is used to establish a TCP (stream) socket that allows you to connect to a TCP server. You can listen for various events, e.g., when connection is established, when incoming data is received or when socket is closed or has errors. The properties include the connected, localAddress, localPort, remoteAddress and remotePort.

The following example shows how to connect to a server, send simple request and receive responses using event handlers. You can see the event handlers and property change in real-time when you run this example.
Client
  var s1 = new network.Socket();
  // Properties: s1.connected= s1.localAddress= s1.localPort= s1.remoteAddress= s1.remotePort=
  s1.addEventListener("connect", function(event) { /* socket connected  */ });
  s1.addEventListener("socketData", function(event) { /* received data  */ });
  s1.addEventListener("ioError", function(event) { /* socket error  */ });
  s1.addEventListener("close", function(event) { /* socket closed  */ });
  s1.addEventListener("propertyChange", function(event) { /* see event.property and event.newValue */ });
  s1.connect("www.google.com", 80);
  s1.writeBytes("GET / HTTP/1.0\n\n");
Use the close() function to close an existing socket. A Socket object is implicitly created by ServerSocket when an incoming connection is received, as described next. The "propertyChange" event is applicable to all the classes described in this document, and allow you to see change in any property of that object.

5. How to use listening TCP (stream) socket?

ServerSocket: The ServerSocket class is used to create a listening TCP (stream) socket that allows you receive inbound TCP connections. You can listen for various events, e.g., when incoming connection is received. A new Socket object is created when an incoming connection is received. The properties include bound, listening, localAddress and localPort.

The following example shows the server and client sides of a simple TCP connection. The server sides implements a simple echo server and the client side connects to the server, sends text messages and receives the echo. You can see the event handlers and property change in real-time when you run this example. First run the server and then the client to see the example in action.
Server
  var s2 = new network.ServerSocket();
  // Relevant properties: s2.bound= s2.listening= s2.localAddress= s2.localPort=
  s2.addEventListener("close", function(event) { /* socket error  */ });
  s2.addEventListener("connect", function(event) { /* incoming connection  */
    var s3 = event.socket;
    // Relevant properties: s3.connected= s3.remoteAddress= s3.remotePort=
    s3.addEventListener("socketData", function(event) { /* received data  */
      s3.writeBytes(event.data);
    });
    s3.addEventListener("close", function(event) { /* socket closed  */ });
    s3.addEventListener("ioError", function(event) { /* socket error  */ });
  });
  s2.bind(8123);
  s2.listen();
Client
  var s4 = new network.Socket();
  // Relevant properties: s4.connected= s4.remoteAddress= s4.remotePort=
  s4.addEventListener("close", function(event) { /* socket error  */ });
  s4.addEventListener("ioError", function(event) { /* socket error  */ });
  s4.addEventListener("socketData", function(event) { /* received data  */ });
  s4.addEventListener("connect", function(event) { /* socket connected  */
    s4.writeBytes("hi there!");
  });
  s4.connect("127.0.0.1", 8123);
Click on to close the client and server sockets. It calls the close() method on the objects.
  s4.close();
  s2.close();

6. How to use UDP (datagram) socket?

DatagramSocket: The DatagramSocket class is used to create UDP (datagram) sockets which can be used for sending as well as receiving. You can listen for various events, e.g., when incoming data is received. The properties include bound, connected, localAddress, localPort, remoteAddress and remotePort.

The following example shows the server and client sides of a simple UDP session. You can see the event handlers and property change in real-time when you run this example. First run the server and then the client to see the example in action.
Server
  var s5 = new network.DatagramSocket();
  // Relevant properties: s5.bound= s5.localAddress= s5.localPort=
  s5.addEventListener("data", function(event) { /* received data  */ });
  s5.addEventListener("ioError", function(event) { /* socket error  */ });
  s5.bind(8123, "0.0.0.0");
  s5.receive();
Client
  var s6 = new network.DatagramSocket();
  s6.addEventListener("ioError", function(event) { /* socket error  */ });
  s6.send("hello there", "127.0.0.1", 8123);

Connected Client
The datagram socket can be connected so that subsequent calls to send() does not need to specify the target address and port.
  var s7 = new network.DatagramSocket();
  // Relevant properties: s7.connected= s7.remoteAddress= s7.remotePort=
  s7.addEventListener("ioError", function(event) { /* socket error  */ });
  s7.connect("127.0.0.1", 8123);
  s7.send("hello from connected client");
A bound datagram socket can also be connected. Use the close() function to close an existing datagram socket.

7. How to use RTP/RTCP (real-time) socket?

RealTimeSocket: The RealTimeSocket class is used to create RTP (real-time transport protocol) and RTCP (real-time transport control protocol) session that uses a pair of UDP sockets. You can listen for various events, e.g., when incoming non-media data is received. The properties include bound, connected, localAddress, localPort, localControlAddress, localControlPort, remoteAddress, remotePort, remoteControlAddress and remoteControlPort.

The RealTimeSocket must be connected before you can send non-media data. We will talk about media data such as audio and video when we describe RealTimeGateway class.

The following example shows the server and client sides of a simple RTP session. You can see the event handlers and property change in real-time when you run this example. First run the server and then the client.
Server
  var s8 = new network.RealTimeSocket();
  // Relevant properties: s8.bound= s8.localAddress= s8.localPort=
  // s8.localControlAddress= s8.localControlPort=
  s8.addEventListener("data", function(event) { /* received data  */ });
  s8.addEventListener("ioError", function(event) { /* socket error  */ });
  s8.bind(8124, "0.0.0.0");
  s8.receive(97);
Client
  var s9 = new network.RealTimeSocket();
  // Relevant properties: s9.bound= s9.connected=
  // s9.localAddress= s9.localPort= s9.localControlAddress= s9.localControlPort=
  // s9.remoteAddress= s9.remotePort= s9.remoteControlAddress= s9.remoteControlPort=
  s9.addEventListener("ioError", function(event) { /* socket error  */ });
  s9.bind(); // don't care which port
  s9.connect("127.0.0.1", 8124);
  s9.send("some non-media data", 97, true);
To use the real-time socket for real-time audio and video data, please see the RealTimeGateway class next. You must call bind() before calling connect() or received(), and you must call connect() before calling send(). The bind() call creates the two datagram sockets. Use the close() function to close an existing real-time socket.

8. How to attach media (audio/video) to real-time socket?

RealTimeGateway: The RealTimeGateway class translates media data between one or two RealTimeSocket object and Flash Player's audio and video. It uses another Flash-VideoIO project for easy integration of your Flash-based audio and video communication with the real-time socket. The Flash-VideoIO project allows you to embed a VideoIO.swf file in your web page and use it for publishing media from local devices or playing remote media. This enables building wide variety of multimedia applications such as video conferencing, recording and movie playback. The Flash-VideoIO project by itself provides the client side of the multimedia applications, but requires a server side that actually does media conferencing. Traditionally, any RTMP-based media server such as rtmplite or Red5 can be used.

This section shows how to use Flash-VideoIO and Flash-Network together to create real-time multimedia applications in your browser without relying on media servers. Essentially, the RealTimeGateway class translates between Flash Player's media and the standard RTP format of RealTimeSocket for both audio and video. The audio codec support is limited to Speex and G.711 and video codec support is limited to H.264/AVC

We will show how to use the gateway class using a simple video flow from one VideoIO instance to another. We need two RealTimeSocket objects per VideoIO instance, one for audio and one for video. Even though Flash Player keeps both audio and video in the same stream, hence the same VideoIO instance, we need to separate them when sending over RTP. The signaling part of how the real-time socket ports are exchanged and what RTP payload types correspond to which codec is outside the scope of Flash Network libraries and need to be performed separately in your web application.

Before creating a RealTimeGateway object, you must embed the VideoIO instances. You may follow the extensive tutorial of Flash-VideoIO on how to embed it in your web page, or simply use the swfobject as shown below.
  swfobject.embedSWF("VideoIO11.swf", "local-video", "240", "180", "11.0.0", "expressInstall.swf", {},
    {"allowScriptAccess": "always", "flashVars": "videoCodec=H264Avc&prefix=network.", "bgcolor": "#ffffff"},
    {"id": "local-video", "name": "local-video"});
For this example, you should embed another instance of VideoIO as "remote-video". Just use the above example again but replace the three instances of "local-video" with "remote-video". Now you should be able to access these two VideoIO instances by name.

The RealTimeGateway object has these read-only properties: publishing, playing, publishurl and playurl. The publishing and playing properties indicate whether the gateway is connected to a VideoIO instance or not, and in what mode -- publish or play. When the gateway is created it sets the playurl and publishurl properties. Your application uses these values to set to the "src" property of a VideoIO instance to attach it to the gateway.

The following example shows the client and server sides of a simple RTP session, the two VideoIO instances and the two RealTimeGateway instances for publisher and player respectively. You should first run the server, then the client, then You can see the event handlers and property change in real-time when you run this example. First run the server and then the client, and then the publisher and player.
Client
  var a1 = new network.RealTimeSocket();
  a1.bind();
  // a1.remoteAddress= a1.remotePort=
  
  var v1 = new network.RealTimeSocket();
  v1.bind();
  // v1.remoteAddress= v1.remotePort=
  
  var gw1 = new network.RealTimeGateway();
  // gw1.publishurl=
  // gw1.publishing=
  gw1.setAudio(a1, {}, {"speex/16000": 96,
                       "pcmu/8000": 0});
  gw1.setVideo(v1, {}, {"h264/90000": 97});
Server
  var a2 = new network.RealTimeSocket(); 
  a2.bind();
  // a2.localAddress= a2.localPort=

  var v2 = new network.RealTimeSocket(); 
  v2.bind();
  // v2.localAddress= v2.localPort=

  var gw2 = new network.RealTimeGateway();
  // gw2.playurl=
  // gw2.playing=
  gw2.setAudio(a2, {96: "speex/16000",
                     0: "pcmu/8000"}, {});
  gw2.setVideo(v2, {97: "h264/90000"}, {});
Publisher
  a1.connect("127.0.0.1", a2.localPort);
  v1.connect("127.0.0.1", v2.localPort);
  var fv1 = getFlashMovie("local-video");
  fv1.setProperty("src", gw1.publishurl);

Alternative content

Get Adobe Flash player

Player
  var fv2 = getFlashMovie("remote-video");
  fv2.setProperty("src", gw2.playurl);



Alternative content

Get Adobe Flash player

Click on to stop the VideoIO and set their "src" properties to null.
  fv1.setProperty("src", null);
  fv2.setProperty("src", null);
  gw1.close(); a1.close(); v1.close(); // order is important: first gw then a1/v1
  gw2.close(); a2.close(); v2.close();

9. What are the licensing terms?

This is a free to use software for developers as well as end-users with no restrictions. The client-side Javascript libraries are open source with no restrictions, and the client-side Flash application SWF and required AIR application are closed source.
© 2011-2012, Intencity Cloud Technologies, LLC.