Sockets Binarios, ActionScript 3 + Java

De las preguntas que más me hacen es como conectar un socket con actionscript. El problema generalmente es que muchos tienen el código correcto para conectarse en ActionScript pero no lo tienen del lado del servidor. Aquí pongo un ejemplo sencillo, 2 proyectos para eclipse uno en Java que es una versión sencilla de un servidor que crea un socket en el puerto 9999 y el otro proyecto en ActionScript para conectarse a este socket.

Lo primero que necesitamos es tener el eclipse instalado así como el plugin de flex para eclipse.

Una vez hecho esto creamos 2 proyectos un proyecto Java que llamaremos QuantiumBinaryConnectionToFlashPlayerBuildedInFlexSocket.

Creamos una clase llamada simpleServer que va a ser nuestra clase principal, osea donde va a estar nuestro método main.

Por la simplicidad de este ejemplo no vamos a hacer un socket complejo, de hecho sólo escribiremos unas cuantas líneas de código en la función main.

Empezamos creando una variable de tipo char que representará el End Of Line de nuestos mensajes, esto es porque es el caracter que le indica al player que el mensaje ha terminado:


char EOF = (char)0x00;

Después, en nuestra funcion main abrimos un try en donde correrá nuestro socket, utilizando las clases ServerSocket y Socket y abriendo una conexión en el puerto 9999, tomando el catch para saber que la sesión ha terminado:


try
{
// create a serverSocket connection on port 9999
ServerSocket s = new ServerSocket(9999);
String msgstr = "";

System.out.println(“Servidor iniciado. Esperando conexión del cliente…”);
// wait for incoming connections
Socket incoming = s.accept();

BufferedReader data_in = new BufferedReader(
new InputStreamReader(incoming.getInputStream()));
PrintWriter data_out = new PrintWriter(incoming.getOutputStream());
}
catch (Exception e)
{
System.out.println(“Conexión terminada”);
}

Una vez creada nuestra conección, creamos un blucle que estará verificando si se recibe algún mensaje, y en caso de que la conexión termine se rompa el bucle:


boolean quit = false;

while (!quit)
{
String msg = data_in.readLine();

if (msg == null) quit = true;
}

 

Finalmente agregamos un pequeño condicional que verificará si el mensaje enviado es salir y en caso de que lo sea termina el bucle, terminando así la ejecución del programa; y en caso contrario que regrese el mismo mensaje que ha sido recibido:


if (msg.trim().equals("salir"))
{
data_out.println("Adios"+EOF);
data_out.flush();
quit = true;

}
else
{
data_out.println(msgstr+EOF);
data_out.flush();
}

Esto es todo lo que necesitamos hacer para tener nuestro servidor local para probar nuestro socket.

Ahora vamos con ActionScript.

Creamos un proyecto Flex AIR® que llamaré por puro gusto egocentrista QChat. En nuestro asqueroso MXML agregamos un TextArea, un TextInput y un Button.

Luego creamos la clase que se conectará a nuestro servidor llamada ChatSocket. Dicha clase será hija de la clase Socket.

Creamos una variable de tipo string a la cual llamaremos response que guardará toda la historia de mensajes recibidos.

 

private var response:String;

 

En el constructor de nuestra clase vamos a inicializar al constructor del padre y llamar a la función según la escuela de los evangelistas de adobe que inicializa los lísteners de nuestro socket.


public function ChatSocket(host:String=null, port:int=0)
{
super(host, port);
configureListeners();
}
private function configureListeners():void
{
addEventListener(Event.CLOSE, closeHandler);
addEventListener(Event.CONNECT, connectHandler);
addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
}

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

private function connectHandler(event:Event):void
{
trace(“connectHandler: ” + event);
}

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

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

private function socketDataHandler(event:ProgressEvent):void
{
trace(“socketDataHandler: ” + event);
}

 

Hasta aquí vamos bien, si no has entendido nada pulsa Alt+F4.

Ahora crearemos una Clase que nos servirá como utilidad ortogonal para nuestro proyecto. Osease que vamos a crear un hijo de la clase Event que se llamará ChatSocketEvent. Este tipo de eventos por el momento sólo serán despachados al momento de recibir un mensaje.


public static const RESPONSE:String = "response";

protected var _message:String;
public function get message():String
{
return _message;
}
public function ChatSocketEvent($type:String, $message:String, $bubbles:Boolean=false, $cancelable:Boolean=false)
{
_message = $message;
super($type, $bubbles, $cancelable);
}

Una vez creado nuestro evento vamos a utilizarlo para enviar el mensaje recibido en la función socketDataHandler en nuestra Clase ChatSocket.


private function socketDataHandler(event:ProgressEvent):void
{
var str:String = readUTFBytes(bytesAvailable);
dispatchEvent(new ChatSocketEvent(ChatSocketEvent.RESPONSE,str));
response += str;
}

Ahora que ya leemos la respuesta del servidor vamos a hacer un método que se encargue de enviar datos llamado say, en este método escribimos los bytes en modo UTF en el socket y hacemos flush, todo esto dentro de un try para cachar cualquier error:


public function say($message:String):void
{
response = "";
$message += "\n";
try {
writeUTFBytes($message);
}
catch(e:IOError) {
trace(e);
}
flush();
}

 

Ahora regresemos a nuestro horroroso MXML.

Creamos la variable _localSocket que será una instancia de nuestra clase ChatSocket


private var _localSocket:ChatSocket = new ChatSocket();

Vamos agregar un método que escuche el evento de inicialización de nuestro AIR, en el cual inicializaremos el socket y agregaremos el evento que escuchará al teclado para que en el momento de presionar enter se envíen los mensajes, dentro del evento ponemos:


_localSocket.addEventListener(ChatSocketEvent.RESPONSE, serverResponse);
_localSocket.connect("localhost", 9999);
addEventListener(KeyboardEvent.KEY_DOWN, keyDown);

Como podemos ver hemos creado dos métodos: serverResponse y keyDown. serverResponse escucha los eventos tirados por nuestro socket y los envía a nuestro TextArea y keyDown escucha cuando el usuario presiona enter y envía el mensaje viva la usabilidad.


protected function serverResponse($evt:ChatSocketEvent):void
{
console.text += "Server :: "+$evt.message+"\n";
}
protected function keyDown($evt:KeyboardEvent):void
{
if($evt.keyCode == Keyboard.ENTER)
{
sendChat();
}
}

 

El evento sendChat que es llamado al presionar ENTER también será llamado al presionar el botón que tenemos en nuestro purulento MXML.


public function sendChat():void
{
_localSocket.say(input.text);
console.text += "Quantium :: "+input.text+"\n";
input.text = "";
}

Para hacer las llamadas desde nuestro componentes hacemos algo como esto:
<mx:TextArea id=”console” width=”100%” height=”100%”/>

<mx:TextInput id=”input” width=”85%”/>

<mx:Button id=”send” label=”Button” width=”10%” textAlign=”center” click=”sendChat()”/>

Y listo, ya está nuestro pequeño Chat. Para probar su funcionamiento puedes descargar o ejecutar el archivo .jar aquí.

Y para descargar la aplicación AIR lo puedes hacer aquí abajo:

Importante: El air no funcionará si el jar no está ya corriendo cuando se ejecute. Primero ejecuta el archivo simpleServer.jar y después el air.

¿Te gustaría tener los archivos fuente de este ejemplo completos y listos para correrse desde eclipse?

¡¡¡Adquiere los Archivos de este tutorial!!

solo 5 dólares

6 Replies to “Sockets Binarios, ActionScript 3 + Java”

  1. “¿Te gustaría tener los archivos fuente de este ejemplo completos y listos para correrse desde eclipse?
    ¡¡¡Adquiere los Archivos de este tutorial!!”

    jaja. eso me hizo reir, sorry…

  2. Bastante chido el tutorial, muchas gracias, el detalle del paypal por los fuentes esta poca madre jajajajaa

    vientos!!!!
    por cierto esta muy chido tu sudo-Q

    chicles

    saludeitors

  3. Bastante chido el tutorial, muchas gracias, el detalle del paypal por los fuentes esta poca madre jajajajaa vientos!!!! por cierto esta muy chido tu sudo-Q chicles saludeitors