package com.renaun.samples.net { import flash.net.NetConnection; import flash.net.SharedObject; import flash.events.NetStatusEvent; import flash.events.SecurityErrorEvent; import flash.events.AsyncErrorEvent; import flash.events.IOErrorEvent import flash.events.Event; import flash.events.IEventDispatcher; import mx.logging.LogLogger; [Event(name="success", type="flash.events.Event")] [Event(name="failed", type="flash.events.Event")] /** * Note: This class was dynamic in ActionScript 2.0 but is now sealed. * To write callback methods for this class, you can either extend the * class and define the callback methods in your subclass, or you can * use the client property to refer to an object and define the callback * methods on that object. */ dynamic public class FMSConnection extends NetConnection implements IEventDispatcher { //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor */ public function FMSConnection() { super(); } public var clientID:Number; //-------------------------------------------------------------------------- // // Methods // //-------------------------------------------------------------------------- /** * Connect */ override public function connect( url:String, ...args ):void { // Set object encoding to be compatible with Flash Media Server this.objectEncoding = flash.net.ObjectEncoding.AMF0; NetConnection.defaultObjectEncoding // Add status/security listeners this.addEventListener( NetStatusEvent.NET_STATUS, netStatusHandler ); this.addEventListener( SecurityErrorEvent.SECURITY_ERROR, netSecurityError ); this.addEventListener( AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler ); this.addEventListener( IOErrorEvent.IO_ERROR, ioErrorHandler ); // TODO does not pass ...args into the super function super.connect( url ); } /** * setID */ public function setId( id:Number ):* { //LogLogger.debug( "FMSConnection::setId: id=" + id,"s"); if( isNaN( id ) ) return; clientID = id; return "Okay"; } /** * Status Handler for the NetConnection class */ private function netStatusHandler( event:NetStatusEvent ):void { switch( event.info.code ) { case "NetConnection.Connect.Success": //Logger.debug( "FMSConnection:netStatusHandler:Success: connected: " + this.connected ); dispatchEvent( new Event( "success" ) ); break; case "NetConnection.Connect.Failed": //Logger.debug( "FMSConnection:netStatusHandler:Failed: connected: " + this.connected + " - " + event.info.code ); dispatchEvent( new Event( "failed" ) ); break; default: //Logger.debug( "FMSConnection:netStatusHandler:code: " + event.info.code ); break; } } private function netSecurityError( event:SecurityErrorEvent ):void { //Logger.error( "FMSConnection:netSecurityError: " + event ); } private function asyncErrorHandler( event:AsyncErrorEvent ):void { //Logger.error( "FMSConnection:asyncErrorHandler: " + event.type + " - " + event.error ); } private function ioErrorHandler( event:IOErrorEvent ):void { //Logger.error( "FMSConnection:asyncErrorHandler: " + event.type + " - " + event.text ); } } }
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" horizontalAlign="center" verticalAlign="middle"> <mx:Style> Application { background-image: ""; background-color: #336699; } Panel, TabNavigator { padding-bottom:10; padding-left:10; padding-right:10; padding-top:10; } .chatBox { background-color: #EEEEEE; } </mx:Style> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.controls.Text; import com.renaun.samples.net.FMSConnection; import mx.controls.Alert; import flash.net.SharedObject; [Bindable] private var nc:FMSConnection; [Bindable] private var btnText:String = "Login"; [Bindable] private var dpUsers:ArrayCollection private var chatUsers:Array; private var clientID:Number; private var soChat:SharedObject; private function connectUser():void { NetConnection.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0; SharedObject.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0; if( txtUser.text != "" && btnText == "Login" ) { nc = new FMSConnection(); nc.addEventListener( "success", connectionSuccessHandler ); // works with nc.connect( "rtmp://localhost/SOSample" ); also nc.connect( "rtmp://192.168.200.14/red" ); } else { if( btnText == "Logout" ) { // Close Connections soChat.close(); nc.close(); btnText = "Login"; } else { Alert.show( "Invalid Name!" ); } } keyEvent(); } private function connectionSuccessHandler( event:Event ):void { btnText = "Logout"; // Get Server Client ID clientID = nc.clientID; // Make SO and other Connection calls connectToChat(); } private function connectToChat():void { soChat = SharedObject.getRemote( "videoConferenceChat", nc.uri, true ); soChat.addEventListener( NetStatusEvent.NET_STATUS, netStatusHandler ); soChat.addEventListener( AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler ); soChat.addEventListener( SyncEvent.SYNC, sharedObjectSyncHandler ); soChat.client = this; soChat.connect( nc ); // trace("helloWorld"); // Get the names for all the connected users soChat.send( "getName" ); } public function sendMessage( msg:String ):void { soChat.send( "newMessage", "<font color=\"#" + cmpColorPicker.selectedColor.toString(16) + "\"><b>" + txtUser.text + "</b></font> - " + msg ); txtMsg.htmlText = ""; } public function newMessage( msg:String ):void { //Logger.info( "newMessage: " + msg ); txtChatBox.htmlText += msg + "\n"; } public function newName( name:String, chatID:Number ):void { //Logger.info( "newName: name: " + name + " chatID: " + chatID ); // initialize if( chatUsers == null ) chatUsers = new Array(); // Only add new users to array var isNew:Boolean = true; for( var i:int = 0; i < chatUsers.length;i++ ) { if( chatUsers[ i ].data == chatID ) { isNew = false; } } if( isNew ) chatUsers.push( { label: name, data: chatID } ); // Sort Users chatUsers.sortOn( "label", Array.CASEINSENSITIVE ); dpUsers = new ArrayCollection( chatUsers ); } public function getName():void { //Logger.info( "getName: " + txtUser.text ); // Clear out User array chatUsers = new Array(); // Getting Users name is basically forcing each connect user to re-send their name soChat.send( "newName", txtUser.text, clientID ); } private function sharedObjectSyncHandler( event:SyncEvent ):void { trace(event.toString()); // Logger.debug( "sharedObjectSyncHandler:code: " + event.changeList ); } private function netStatusHandler( event:NetStatusEvent ):void { trace(event.info); // Logger.debug( "netStatusHandler:code: " + event.info.code ); } private function asyncErrorHandler( event:AsyncErrorEvent ):void { trace(event.toString()); // Logger.debug( "asyncErrorHandler:code: " + event.error ); } ]]> </mx:Script> <mx:Panel width="90%" height="90%" title="Basic Chat Application using Flex 3 and Red5" layout="vertical"> <mx:HBox width="100%"> <mx:Label text="Name:"/> <mx:TextInput id="txtUser" enabled="{ ( btnText == 'Login' ) }"/> <mx:ColorPicker id="cmpColorPicker" showTextField="false" selectedColor="0x000000"/> <mx:Button id="btnLogin" label="{ btnText }" click="connectUser()"/> </mx:HBox> <mx:HDividedBox width="100%" height="100%"> <mx:VBox width="25%" height="100%"> <mx:Label text="Chat Users:" /> <mx:List id="lstUsers" dataProvider="{ dpUsers }" width="100%" height="100%" /> </mx:VBox> <mx:VBox width="75%" height="100%"> <mx:TabNavigator width="100%" height="100%"> <mx:VBox label="Main Chat"> <mx:TextArea fontSize="18" id="txtChatBox" styleName="chatBox" editable="false" width="100%" height="100%" fontWeight="bold" textAlign="left"/> </mx:VBox> </mx:TabNavigator> <mx:HBox width="100%"> <mx:TextInput width="100%" id="txtMsg"/> <mx:Button id="btnMessage" label="Send Message" click="sendMessage( txtMsg.text )" /> </mx:HBox> </mx:VBox> </mx:HDividedBox> </mx:Panel> <mx:Script> <![CDATA[ public function keyEvent(){ txtMsg.addEventListener(KeyboardEvent.KEY_DOWN,sendM) } public function sendM(e:KeyboardEvent){ if(e.keyCode==13){ sendMessage(txtMsg.text); } } ]]> </mx:Script> </mx:Application>