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.
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.
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:
active
whether the interface is active or not?
name
the unique name of the interface.
addresses
an array of IP addresses.
Each address item is an object with these attributes:
ipVersion
either "IPv4" or "IPv6".
address
the IP address on this interface for this IP version.
broadcast
the broadcast address on this interface for this IP version.
prefixLength
the network mask's prefix length.
hardwareAddress
the hardware or MAC address.
displayName
a displayable name if available.
mtu
the value of MTU in bytes.
parent
any parent interface name if applicable.
subInterfaces
array 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
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.
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
Player
var fv2 = getFlashMovie("remote-video");
fv2.setProperty("src", gw2.playurl);
Alternative content
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.