Tickets used in Paris
Some of the train tickets that were used while in Paris, France.

XIFF chat - Part 1

This set of examples, of which this is the first, show how to build a basic XMPP based chat in Actionscript 3 by using the XIFF library from Ignite Realtime.

You will need a recent copy of the XIFF library. You can get it with a Subversionclient:

svn co -r 11106 http://svn.igniterealtime.org/svn/repos/xiff/trunk/src/org org

The example code below demonstrates a simple chat with anonymous login. You can compile it for example with Adobe Flex 3 SDK.

API documentation for the library can be found at paazio.wippiespace.com/xiff3doc.

package
{
    import flash.display.*;
    import flash.events.*;
    import flash.text.*;
    import flash.utils.Timer;
    import flash.system.Security;
    import flash.ui.Keyboard;

    import org.igniterealtime.xiff.core.*;
    import org.igniterealtime.xiff.data.*;
    import org.igniterealtime.xiff.events.*;

    [SWF(backgroundColor = '0x5B5B5B', frameRate = '33', width = '600', height = '400')]

    /**
     * @see http://paazmaya.fi/xiff-chat-part-1
     */
    public class XIFFstep1 extends Sprite
    {
        private const SERVER:String = "192.168.1.37";
        private const PORT:Number = 5222;
        private const USERNAME:String = "flasher";
        private const PASSWORD:String = "flasher";
        private const RESOURCE_NAME:String = "flashPlayer";
        private const CHECK_POLICY:Boolean = true;

        private var _connection:XMPPSocketConnection;
        private var _keepAlive:Timer;
        private var _outputField:TextField;
        private var _inputField:TextField;
        private var _chattingWith:EscapedJID = new EscapedJID("tonttu@" + SERVER);

        public function XIFFstep1()
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;

            loaderInfo.addEventListener(Event.INIT, onInit);
        }

        private function onInit(event:Event):void
        {
            if (CHECK_POLICY)
            {
                Security.loadPolicyFile("xmlsocket://" + SERVER + ":5229");
            }
            createElements();

            initChat();
        }

        private function createElements():void
        {
            var format:TextFormat = new TextFormat("Verdana", 12, 0x121212);

            _outputField = new TextField();
            _outputField.background = true;
            _outputField.backgroundColor = 0xCCCCCC;
            _outputField.mouseWheelEnabled = true;
            _outputField.multiline = true;
            _outputField.width = stage.stageWidth - 4;
            _outputField.height = stage.stageHeight - 54;
            _outputField.x = 2;
            _outputField.y = 2;
            addChild(_outputField);

            _inputField = new TextField();
            _inputField.background = true;
            _inputField.backgroundColor = 0xEEEEEE;
            _inputField.type = "input";
            _inputField.width = stage.stageWidth - 4;
            _inputField.height = 48;
            _inputField.x = 2;
            _inputField.y = stage.stageHeight - 50;
            _inputField.maxChars = 40;
            _inputField.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
            addChild(_inputField);
        }

        private function addMessage(from:EscapedJID, msg:String):void
        {
            var date:Date = new Date();
            _outputField.appendText("[" + date.getHours() + ":" + date.getMinutes() + " | " + from.node + "] " + msg + "\n");
        }

        private function onKeyUp(event:KeyboardEvent):void
        {
            switch(event.keyCode)
            {
                case Keyboard.ENTER :
                    messageSend();
                    break;
            }
        }

        private function messageSend():void
        {
            var txt:String = _inputField.text;
            var msg:Message = new Message(_chattingWith, null, txt, null, Message.CHAT_TYPE);
            if (_connection.isLoggedIn())
            {
                _connection.send(msg);
                _inputField.text = "";
                addMessage(_connection.jid.escaped, txt);
            }
        }

        private function initChat():void
        {
            _connection = new XMPPSocketConnection();

            _connection.addEventListener(DisconnectionEvent.DISCONNECT, onDisconnect);
            _connection.addEventListener(XIFFErrorEvent.XIFF_ERROR, onXiffError);
            _connection.addEventListener(LoginEvent.LOGIN, onLogin);
            _connection.addEventListener(MessageEvent.MESSAGE, onMessage);

            _connection.useAnonymousLogin = true;
            _connection.server = SERVER;
            _connection.port = PORT;
            _connection.resource = RESOURCE_NAME;
            _connection.connect("flash");

            _keepAlive = new Timer(2 * 60 * 1000);
            _keepAlive.addEventListener(TimerEvent.TIMER, onKeepAliveLoop);
        }

        private function onDisconnect(event:DisconnectionEvent):void
        {
            trace("onDisconnect. " + event.toString());
        }

        private function onXiffError(event:XIFFErrorEvent):void
        {
            trace("onXiffError. " + event.toString());
            trace("onXiffError.errorMessage: " + event.errorMessage);
        }

        private function onLogin(event:LoginEvent):void
        {
            trace("onLogin. " + event.toString());
            _keepAlive.start();

            // http://www.ietf.org/rfc/rfc3921.txt
            var presence:Presence = new Presence(null, _connection.jid.escaped, null, null, null, 1);
            _connection.send(presence);
        }

        private function onMessage(event:MessageEvent):void
        {
            trace("onMessage. " + event.toString());
            addMessage(event.data.from, event.data.body);
        }

        private function onKeepAliveLoop(event:TimerEvent):void
        {
            _connection.sendKeepAlive();
        }
    }
}

Make sure anonymous logins are allowed on the server you are trying to connect with this script. Also remember to set _chattingWith into something more appropriate, this is the other person in your instant messaging.