I have just discovered the ServerSocket class and I have made an AIR2 (required) server socket application with it. I’ve tested it locally so far (127.0.0.1, 0.0.0.0 ) and it seems to be working fine with a regular application I made using Socket to talk with it. I tried getting another copy of the socket app to talk to the socket server from another machine on the network, but I think a LAN might work better for testing at the moment since I don’t know the dynamics of the huge network that exists at work.
I will be adding some code to this post once I’m sure it’s mostly worked out. The socket server is made outside of Flex, but that shouldn’t change much if you are using Flex to author your AIR 2 application.
Here is an event class I am using with my socket class:
package { import flash.events.Event; public class SocketEvent extends Event { public static const DATA_RECEIVED:String = "received"; public static const CONNECTED:String = "connected"; public var params:Object; public function SocketEvent( $type:String, $params:Object, $bubbles:Boolean = false, $cancelable:Boolean = false ){ super( $type, $bubbles, $cancelable ); this.params = $params; } public override function clone():Event { return new SocketEvent( type, this.params, bubbles, cancelable ); } public override function toString():String { return formatToString("SocketEvent", "params", "type", "bubbles", "cancelable" ); } } }
And here is a socket server class (in an unfit state, but I present it prior to clean-up and testing):
package { import flash.display.Sprite; import flash.errors.IOError; import flash.events.Event; import flash.events.MouseEvent; import flash.events.ProgressEvent; import flash.events.ServerSocketConnectEvent; import flash.net.ServerSocket; import flash.net.Socket; import flash.text.TextField; import flash.text.TextFieldType; import flash.utils.ByteArray; public class SocketServer extends Sprite { private var serverSocket:ServerSocket = new ServerSocket(); private var clientSocket:Socket; public function SocketServer(){ setupUI(); } private function onConnect( event:ServerSocketConnectEvent ):void { clientSocket = event.socket; clientSocket.addEventListener( ProgressEvent.SOCKET_DATA, onClientSocketData ); log( "Connection from " + clientSocket.remoteAddress + ":" + clientSocket.remotePort ); } private function onClientSocketData( event:ProgressEvent ):void { var buffer:ByteArray = new ByteArray(); clientSocket.readBytes( buffer, 0, clientSocket.bytesAvailable ); var recString:String = buffer.toString(); recString = recString.replace(/\n/g,''); recString = recString.replace(/\r/g,''); //log( "Received: " + buffer.toString() ); log( "Received: " + recString ); } private function bind( event:Event ):void { if( serverSocket.bound ) { serverSocket.close(); serverSocket = new ServerSocket(); } try { serverSocket.bind( parseInt( localPort.text ), localIP.text ); } catch( error:Error ){ log( "Error: bind() attempted on invalid socket." ); } serverSocket.addEventListener( ServerSocketConnectEvent.CONNECT, onConnect ); serverSocket.listen(); bound_txt.text = "Bound to " + serverSocket.localAddress + ":" + serverSocket.localPort; } private function send( event:Event ):void { try{ if( clientSocket != null && clientSocket.connected ){ clientSocket.writeUTFBytes( message.text ); clientSocket.flush(); log( "Sent message to " + clientSocket.remoteAddress + ":" + clientSocket.remotePort ); } else log("No socket connection."); } catch ( error:Error ){ log( error.message ); } } private function log( text:String ):void { logField.appendText( text + "\n" ); logField.scrollV = logField.maxScrollV; trace( text ); } private function setupUI():void { bind_btn.addEventListener( MouseEvent.CLICK, bind ); send_btn.addEventListener( MouseEvent.CLICK, send ); clear_btn.addEventListener( MouseEvent.CLICK, clear ); this.stage.nativeWindow.activate(); } private function clear( event:MouseEvent ):void { logField.text = ""; } } }
I can’t wait to post up code.
Thanks for this post – the code is very easy to follow (though probably because it adheres to the conventions set by the documentation) and it’s a lot easier to understand than the Adobe article on it (documentation? http://www.adobe.com/devnet/air/flex/quickstart/articles/communicating_with_sockets.html) that I personally had a lot of trouble setting up because of things like imports and, specifically, communicating with the client socket upon establishing a connection.