Question

my problem is the following:

I have an actionscript class that represents a socketclient. This code works. In addition to that I have a Main.mxml file with fx:script code (In my original file there is a huge GUI connected, in this case here I made it simple)

So what I want: I want to call methods when receiving information from the Socket. So I would like to call methods that are in the mxml file from the actionscript class. As an alternative I want to send events to the mxml file that can be processed there. I read a lot about import/include stuff and so on, but nothing really helped.

So here is my code: Actionscript file SocketExample.as:

// http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/Socket.html

package {
import flash.display.Sprite;

public class SocketExample extends Sprite {
    private var socket:CustomSocket;

    public function SocketExample() {
        socket = new CustomSocket("localhost", 80);
    }
}
}

import flash.errors.*;
import flash.events.*;
import flash.net.Socket;

class CustomSocket extends Socket {
private var response:String;

public function CustomSocket(host:String = null, port:uint = 0) {
    super();
    configureListeners();
    if (host && port)  {
        super.connect(host, port);
    }
}

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 writeln(str:String):void {
    str += "\n";
    try {
        writeUTFBytes(str);
    }
    catch(e:IOError) {
        trace(e);
    }
}

private function sendRequest():void {
    trace("sendRequest");
    response = "";
    writeln("GET /");
    flush();
}

private function readResponse():void {
    var str:String = readUTFBytes(bytesAvailable);
    response += str;
    trace(response);



    //
        //  Here I want to call the method 
    //
}

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

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

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);
    readResponse();
}
}

Here is the Main.mxml file called HelloSocket.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                   xmlns:s="library://ns.adobe.com/flex/spark" 
                   xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>


<fx:Script>
    <![CDATA[
        public function HelloWorld():void{
            HelloLabel.text = "Hello World";
        }


    ]]>
</fx:Script>
<s:Label id="HelloLabel" x="150" y="180" text="Hello" fontSize="20" fontWeight="bold"/>
</s:WindowedApplication>

so HelloWorld() is the function I want to call here. Important is also that GUI and SocketClient (as class) are running at the same time. This is the complete example code that I have.

Please tell me everything I need to make this example work, beginning from imports and includes, to event handling or method calling

Best would be to change directly my code and explain. I thank you very much in advance

If you would like to test it, here is a matching java socket server:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;


public class SocketServer {
public static void main (String args[]) throws IOException {

      ServerSocket mySocketServer = new ServerSocket(80);

      System.out.print("Waiting for FlashClient ...\n");
      Socket mySocket = mySocketServer.accept();

      System.out.print("FlashClient connected.\n\n");

      mySocketServer.close();   

      InputStream in = mySocket.getInputStream();
      OutputStream out = mySocket.getOutputStream();

      byte buffer[] = new byte[1];
      int i = 5;

      do
      {
        // i = in.read(buffer, 0, 1);
        if (i>-1)  out.write("Hello World".getBytes("UTF-8"));
        try {
            Thread.sleep (300);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
      } while(i>-1);

      System.out.print("Lost connection to FlashClient.\n\n");

      in.close();
      out.close();

      mySocket.close();

}

}
Was it helpful?

Solution 2

Thank you Christophe. So here is the solution to my problem.

First, I needed an instance of the actionScript in the script are of my mxml file:

protected var socketEx:SocketExample = new SocketExample();

Then I had to change the methods in my mxml file a bit:

        protected function HelloWorld(event:FlexEvent):void
        {
            socketEx.socket.addEventListener("test", Function1);

        }

        protected function Function1(e:Event):void{
            HelloLabel.text = "World";
        }

The HelloWorld method is called on creationComplete It adds an EventListener. The event is dispatched in my actionScript class:

private function readResponse():void {
    var str:String = readUTFBytes(bytesAvailable);
    response += str;

    trace(response);

    this.dispatchEvent(new Event("test"));

}

So to use it here is the complete code now: SocketExample.as : // http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/Socket.html

package {
import flash.display.Sprite;

public class SocketExample extends Sprite {
    public var socket:CustomSocket;

    public function SocketExample() {
        socket = new CustomSocket("localhost", 80);
    }
}
}

import flash.errors.*;
import flash.events.*;
import flash.net.Socket;

class CustomSocket extends Socket {
public var response:String;

public function CustomSocket(host:String = null, port:uint = 0) {
    super();
    configureListeners();
    if (host && port)  {
        super.connect(host, port);
    }
}

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 writeln(str:String):void {
    str += "\n";
    try {
        writeUTFBytes(str);
    }
    catch(e:IOError) {
        trace(e);
    }
}

private function sendRequest():void {
    trace("sendRequest");
    response = "";
    writeln("GET /");
    flush();
}

private function readResponse():void {
    var str:String = readUTFBytes(bytesAvailable);
    response += str;

    trace(response);

    this.dispatchEvent(new Event("test"));

}

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

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

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);
    readResponse();
}
}

HelloSocket.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                   xmlns:s="library://ns.adobe.com/flex/spark" 
                   xmlns:mx="library://ns.adobe.com/flex/mx"
                   creationComplete="HelloWorld(event)">
<fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>


<fx:Script>
    <![CDATA[
        import mx.events.FlexEvent;
        protected var socketEx:SocketExample = new SocketExample();

        protected function HelloWorld(event:FlexEvent):void
        {
            socketEx.socket.addEventListener("test", Function1);

        }

        protected function Function1(e:Event):void{
            HelloLabel.text = "World";
        }



    ]]>
</fx:Script>
<s:Label id="HelloLabel" x="150" y="180" text="Hello" fontSize="20" fontWeight="bold"/>
</s:WindowedApplication>

I hope that helps somebody. So this is how to send messages from a Java SocketServer (see code in my question) , receive it in flash and use it in the script code of the .mxml file

OTHER TIPS

Your mxml files is your main application file. That means that you will have to create an instance of your CustomSocket there and listen for events from it.

Since the relationship from your main application to your socket is top-down, the way the socket communicates with the application is via events and not via direct method invocations. When the data comes in and you want to inform the application from within the socket, dispatch an event.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top