View comments | RSS feed

Socket connections

There are two different types of socket connections possible in ActionScript 3.0: XML socket connections and binary socket connections. An XML socket lets you connect to a remote server and create a server connection that remains open until explicitly closed. This lets you exchange XML data between a server and client without having to continually open new server connections. Another benefit of using an XML socket server is that the user doesn't need to explicitly request data. You can send data from the server without requests, and you can send data to every client connected to the XML socket server.

A binary socket connection is similar to an XML socket except that the client and server don't need to exchange XML packets specifically. Instead, the connection can transfer data as binary information. This allows you to connect to a wide range of services, including mail servers (POP3, SMTP, and IMAP), and news servers (NNTP).

Subtopics

Socket class
XMLSocket class
Creating and connecting to a Java XML socket server

Socket class

Introduced in ActionScript 3.0, the Socket class enables ActionScript to make socket connections and to read and write raw binary data. It is similar to the XMLSocket class, but does not dictate the format of the received and transmitted data. The Socket class is useful for interoperating with servers that use binary protocols. By using binary socket connections, you can write code that allows interaction with several different Internet protocols, such as POP3, SMTP, IMAP, and NNTP. This in turn enables Flash Player to connect to mail and news servers.

Flash Player can interface with a server by using the binary protocol of that server directly. Some servers use the big-endian byte order, and some use the little-endian byte order. Most servers on the Internet use the big-endian byte order because "network byte order" is big-endian. The little-endian byte order is popular because the Intel® x86 architecture uses it. You should use the endian byte order that matches the byte order of the server that is sending or receiving data. All operations that are performed by the IDataInput and IDataOutput interfaces, and the classes that implement those interfaces (ByteArray, Socket, and URLStream), are encoded by default in big-endian format; that is, with the most significant byte first. This is done to match Java and official network byte order. To change whether big-endian or little-endian byte order is used, you can set the endian property to Endian.BIG_ENDIAN or Endian.LITTLE_ENDIAN.

TIP

 

The Socket class inherits all the methods implemented by the IDataInput and IDataOutput interfaces (located in the flash.utils package), and those methods should be used to write to and read from the Socket.

XMLSocket class

ActionScript provides a built-in XMLSocket class, which lets you open a continuous connection with a server. This open connection removes latency issues and is commonly used for real-time applications such as chat applications or multiplayer games. A traditional HTTP-based chat solution frequently polls the server and downloads new messages using an HTTP request. In contrast, an XMLSocket chat solution maintains an open connection to the server, which lets the server immediately send incoming messages without a request from the client.

To create a socket connection, you must create a server-side application to wait for the socket connection request and send a response to the SWF file. This type of server-side application can be written in a programming language such as Java, Python, or Perl. To use the XMLSocket class, the server computer must run a daemon that understands the protocol used by the XMLSocket class. The protocol is described in the following list:

NOTE

 

The XMLSocket class cannot tunnel through firewalls automatically because, unlike the Real-Time Messaging Protocol (RTMP), XMLSocket has no HTTP tunneling capability. If you need to use HTTP tunneling, consider using Flash Remoting or Flash Media Server (which supports RTMP) instead.

The following restrictions apply to how and where an XMLSocket object can connect to the server:

NOTE

 

Setting up a server to communicate with the XMLSocket object can be challenging. If your application does not require real-time interactivity, use the URLLoader class instead of the XMLSocket class.

You can use the XMLSocket.connect() and XMLSocket.send() methods of the XMLSocket class to transfer XML to and from a server over a socket connection. The XMLSocket.connect() method establishes a socket connection with a web server port. The XMLSocket.send() method passes an XML object to the server specified in the socket connection.

When you invoke the XMLSocket.connect() method, Flash Player opens a TCP/IP connection to the server and keeps that connection open until one of the following occurs:

Creating and connecting to a Java XML socket server

The following code demonstrates a simple XMLSocket server written in Java that accepts incoming connections and displays the received messages in the command prompt window. By default, a new server is created on port 8080 of your local machine, although you can specify a different port number when starting your server from the command line.

Create a new text document and add the following code:

import java.io.*;
import java.net.*;

class SimpleServer
{
    private static SimpleServer server;
    ServerSocket socket;
    Socket incoming;
    BufferedReader readerIn;
    PrintStream printOut;

    public static void main(String[] args)
    {
        int port = 8080;

        try
        {
            port = Integer.parseInt(args[0]);
        }
        catch (ArrayIndexOutOfBoundsException e)
        {
            // Catch exception and keep going.
        }

        server = new SimpleServer(port);
    }

    private SimpleServer(int port)
    {
        System.out.println(">> Starting SimpleServer");
        try
        {
            socket = new ServerSocket(port);
            incoming = socket.accept();
            readerIn = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
            printOut = new PrintStream(incoming.getOutputStream());
            printOut.println("Enter EXIT to exit.\r");
            out("Enter EXIT to exit.\r");
            boolean done = false;
            while (!done)
            {
                String str = readerIn.readLine();
                if (str == null)
                {
                    done = true;
                }
                else
                {
                    out("Echo: " + str + "\r");
                    if(str.trim().equals("EXIT"))
                    {
                        done = true;
                    }
                }
                incoming.close();
            }
        }
        catch (Exception e)
        {
            System.out.println(e);
        }
    }

    private void out(String str)
    {
        printOut.println(str);
        System.out.println(str);
    }
}

Save the document to your hard disk as SimpleServer.java and compile it using a Java compiler, which creates a Java class file named SimpleServer.class.

You can start the XMLSocket server by opening a command prompt and typing java SimpleServer. The SimpleServer.class file can be located anywhere on your local computer or network; it doesn't need to be placed in the root directory of your web server.

TIP

 

If you're unable to start the server because the files are not located within the Java classpath, try starting the server with java -classpath . SimpleServer.

To connect to the XMLSocket from your ActionScript application, you need to create a new instance of the XMLSocket class, and call the XMLSocket.connect() method while passing a host name and port number, as follows:

var xmlsock:XMLSocket = new XMLSocket();
xmlsock.connect("127.0.0.1", 8080);

A securityError (flash.events.SecurityErrorEvent) event occurs if a call to XMLSocket.connect() attempts to connect either to a server outside the caller's security sandbox or to a port lower than 1024.

Whenever you receive data from the server, the data event (flash.events.DataEvent.DATA) is dispatched:

xmlsock.addEventListener(DataEvent.DATA, onData);
private function onData(event:DataEvent):void
{
    trace("[" + event.type + "] " + event.data);
}

To send data to the XMLSocket server, you use the XMLSocket.send() method and pass an XML object or string. Flash Player converts the supplied parameter to a String object and sends the content to the XMLSocket server followed by a zero (0) byte:

xmlsock.send(xmlFormattedData);

The XMLSocket.send() method does not return a value that indicates whether the data was successfully transmitted. If an error occurred while trying to send data, an IOError error is thrown.

TIP

 

Each message you send to the XML socket server must be terminated by a newline (\n) character.


Flash CS3


Comments


nosignal said on Jun 13, 2007 at 10:30 PM :
regarding http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000318.html

The Java sample code here seemed to have a lot (about 5) problems with it, so I spent the better part of my day fixing it. It now works great, and easier to understand for a novice. I have pasted it beolw:

import java.io.*;
import java.net.*;

class SimpleServer
{
private static SimpleServer server;
ServerSocket socket;
Socket incoming;
BufferedReader readerIn;
PrintStream printOut;

public static void main(String[] args)
{
int port = 9001;

try
{
port = Integer.parseInt(args[0]);
}
catch (ArrayIndexOutOfBoundsException e)
{
// Catch exception and keep going.
}

server = new SimpleServer(port);
}

private SimpleServer(int port)
{
System.out.println(">> Starting SimpleServer2"); // Sent to console
try
{
socket = new ServerSocket(port);
incoming = socket.accept(); // Waits here until connection is established
readerIn = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
printOut = new PrintStream(incoming.getOutputStream());
out("Enter EXIT to exit."); // Sent to Socket AND console
boolean done = false;
while (!done)
{
String str = readerIn.readLine();
if (str == null)
{
done = true;
}
else
{
str = str.trim();
System.out.println("input: [" + str + "]\r"); // Sent to console
out("Echoing Back: " + str); // Sent to Socket AND console
if(str.trim().equals("EXIT"))
{
done = true;
}
}
}
incoming.close();
}
catch (Exception e)
{
System.out.println("End Exception: " + e); // Sent to console
}
}

private void out(String str)
{
printOut.println(str + "0000"); // Sent to Socket
System.out.println("output: [" + str + "]"); // Sent to console
}
}



You may also want to mention to people that if they don't have a Java SDK installed, they can compile their .java file online at http://www.innovation.ch/java/java_compile.htm


If you are interested, I have also pasted below the AS2 code I used to make the corresponding flash app.



createSocket ();

function createSocket () {

// Set up the GUI
_root.createTextField("inputlabel",4,20,20,50,20);
inputlabel.text = "Input:";
_root.createTextField("outputlabel",5,20,50,50,20);
outputlabel.text = "Output:";
_root.createTextField("tracelabel",6,20,80,50,20);
tracelabel.text = "Tracer:";
_root.createTextField("inputer", 3,70,20,200,20);
_root.createTextField("outputer",2,70,50,200,20);
_root.createTextField("tracer", 7,100,80,400,300);
outputer.type = "input";
outputer.border = true;
inputer.border = true;
tracer.border = true;

// Set Up the Comms
serialServer = new XMLSocket ();
//trace ("made it" + serialServer);
tracer.text = tracer.text + "made it" + serialServer + newline;
//127.0.0.1 is the same as "localhost" ie an alias to your local machine
//it is concievable to that you would want to connect from another machine and you would change this
serialServer.connect ("127.0.0.1", 9001);
serialServer.onConnect = function (success) {
//trace ("connected " + success);
tracer.text = tracer.text + "connected " + success + newline;
serialServer.send ("HOWDY FROM FLASH " + new Date().toString() + newline);
};
serialServer.onClose = function () {
//trace ("closed");
tracer.text = tracer.text + "closed" + newline;
};
serialServer.onData = function (data) {
//trace ("incoming: " + data);
//tracer.text = tracer.text + "[0]=" + data.charCodeAt(0) + newline;
//tracer.text = tracer.text + "[1]=" + data.charCodeAt(1) + newline;
if (data.charCodeAt(0) == 13 && data.charCodeAt(1) == 10) {
data = data.slice( 2, data.length+1 );
}
tracer.text = tracer.text + "incoming: " + data + newline;
inputer.text = inputer.text + data;
};
/*
outputer.onChanged = function () {
serialServer.send (outputer.text + newline);
//trace ("output: " + outputer.text);
tracer.text = tracer.text + "output: " + outputer.text + newline;
outputer.text = "";
};
*/
var keyListener:Object = new Object();
keyListener.onKeyDown = function() {
//trace("For the last key typed, Key code is: " + Key.getCode() + ",ASCII value is: " + Key.getAscii() + newline);
//tracer.text = tracer.text + "For the last key typed, Key code is: " + Key.getCode() + ",ASCII value is: " + Key.getAscii() + newline;
if (Key.getCode()==13) {
serialServer.send (outputer.text + newline);
//trace ("output: " + outputer.text);
tracer.text = tracer.text + "output: " + outputer.text + newline;
outputer.text = "";
}
};
Key.addListener(keyListener);

}





I hope you find that useful - if so, it would be nice if you coule let me know.

Thanks
No screen name said on Jun 21, 2007 at 3:08 AM :
Hi!
Your code works in one direction only. I can send message from as to java, but not from java to as.. could u help me?
Gooberholtzer said on Aug 10, 2007 at 7:43 PM :
This line ...
printOut.println(str + "0000"); // Sent to Socket

needs to be changed to this line to get communication from the Java code to the AS to work.
printOut.println(str + " "); // Sent to Socket
tnagel said on Aug 23, 2007 at 3:21 AM :
Apparently in the last comment the correct character was discarded. Use this line to get it working:

printOut.println(str + (char)0);
rpkhatri said on Feb 20, 2008 at 10:22 AM :
Please can i have a good working example of AS3 XMLSocket class, on this page. which i can use.

OR

a solution to:

I am having an error while compiling.

TypeError: Error #1006: value is not a function.
at KPASA_Client1_fla::MainTimeline/connectHandler()



the code i m using is as follows:

package {
import flash.display.Sprite;
import flash.events.*;
import flash.net.XMLSocket;

public class XMLSocketExample extends Sprite {
private var hostName:String = "localhost";
private var port:uint = 8888;
private var socket:XMLSocket;

public function XMLSocketExample() {
socket = new XMLSocket();
configureListeners(socket);
socket.connect(hostName, port);
}

public function send(data:Object):void {
socket.send(data);
}

private function configureListeners(dispatcher:IEventDispatcher):void {
dispatcher.addEventListener(Event.CLOSE, closeHandler);
dispatcher.addEventListener(Event.CONNECT, connectHandler);
dispatcher.addEventListener(DataEvent.DATA, dataHandler);
dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
}

private function closeHandler(event:Event):void {
trace("closeHandler: " + event);
}

private function connectHandler(event:Event) {
//trace("connectHandler: " + event);
}

private function dataHandler(event:DataEvent):void {
trace("dataHandler: " + event);
}

private function ioErrorHandler(event:IOErrorEvent):void {
trace("ioErrorHandler: " + event);
}

private function progressHandler(event:ProgressEvent):void {
trace("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);
}

private function securityErrorHandler(event:SecurityErrorEvent):void {
trace("securityErrorHandler: " + event);
}
}
}

 

RSS feed | Send me an e-mail when comments are added to this page | Comment Report

Current page: http://livedocs.adobe.com/flash/9.0/main/00000318.html