使用 mxml 脚本代码连接 ActionScript 类(Socket)

Posted

技术标签:

【中文标题】使用 mxml 脚本代码连接 ActionScript 类(Socket)【英文标题】:Connect ActionScript class (Socket) with mxml Script code 【发布时间】:2013-05-01 19:36:02 【问题描述】:

我的问题如下:

我有一个代表 socketclient 的 actionscript 类。此代码有效。 除此之外,我还有一个带有 fx:script 代码的 Main.mxml 文件(在我的原始文件中连接了一个巨大的 GUI,在这种情况下,我把它简单化了)

所以我想要什么: 我想在从 Socket 接收信息时调用方法。所以我想从 actionscript 类中调用 mxml 文件中的方法。 作为替代方案,我想将事件发送到可以在那里处理的 mxml 文件。 我读了很多关于导入/包含的东西等等,但没有任何帮助。

这是我的代码: 动作脚本文件 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();


这里是名为 HelloSocket.mxml 的 Main.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>

所以 HelloWorld() 是我想在这里调用的函数。 重要的是 GUI 和 SocketClient(作为类)同时运行。 这是我拥有的完整示例代码。

请告诉我使这个示例工作所需的一切,从导入和包含开始,到事件处理或方法调用

最好直接更改我的代码并进行解释。 提前非常感谢你

如果你想测试它,这里有一个匹配的 java 套接字服务器:

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




【问题讨论】:

您不能确定消息不会被拆分成多个部分,从而破坏了 readMessage。出于这个原因,我建议您使用在内部等待 \0 并将消息的所有小片段粘合在一起的 XMLSocket。确保从服务器添加 \0 ,以便客户端知道它已结束消息。还要检查服务器是否已经添加了\0。 谢谢,我会检查这个 【参考方案1】:

您的 mxml 文件是您的主要应用程序文件。这意味着您必须在那里创建一个 CustomSocket 实例并从中侦听事件。

由于从主应用程序到套接字的关系是自上而下的,因此套接字与应用程序通信的方式是通过事件而不是通过直接方法调用。当数据进来并且您想从套接字中通知应用程序时,分派一个事件。

【讨论】:

【参考方案2】:

谢谢克里斯托夫。所以这是我的问题的解决方案。

首先,我需要一个脚本中的 actionScript 实例是我的 mxml 文件:

protected var socketEx:SocketExample = new SocketExample();

然后我不得不稍微更改一下我的 mxml 文件中的方法:

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

        

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

在创建完成时调用 HelloWorld 方法 它添加了一个 EventListener。该事件在我的 actionScript 类中调度:

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

    trace(response);

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


所以在这里使用它是完整的代码: 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>

我希望这对某人有所帮助。所以这就是如何从 Java SocketServer 发送消息(参见我的问题中的代码),在 flash 中接收它并在 .mxml 文件的脚本代码中使用它

【讨论】:

以上是关于使用 mxml 脚本代码连接 ActionScript 类(Socket)的主要内容,如果未能解决你的问题,请参考以下文章

从 Flex - mxml(动作脚本)迁移到另一种技术

PHP PHP与MXML上传文件脚本一起使用

PHP与MXML上传文件脚本一起使用

从Flex-mxml(动作脚本)移动到另一种技术

如何将自定义类导入 Flex 中的 mxml 文件? (动作脚本 3)

从外部 AS 访问 MXML 中定义的元素