【问题标题】:Listen for incoming connections in AS3 (AIR) Client whithout using Server Socket在不使用服务器套接字的情况下侦听 AS3 (AIR) 客户端中的传入连接
【发布时间】:2012-12-06 15:28:55
【问题描述】:

我设法创建了一个 C# 服务器,它使用 sockets 将文件发送到 AS3(AIR) 客户端。在 AS3 方面,我使用flash.net.Socket 库通过TCP 接收数据。

这就是它的工作原理:
-> 我打开我的服务器,它会监听客户端(另外我可以创建一个已连接设备的列表);
-> 我打开我的客户端,它会自动接收数据;

接收数据的触发事件是在客户端进行的,即我只是打开服务器,当客户端打开时,它会获取数据,触发这些事件:

socket.addEventListener(Event.CONNECT, onConnect); -> to connect to the server  
socket.addEventListener(Event.SOCKET_DATA, onDataArrival); -> to receive the data  

现在我想做一些不同的事情。我不想在客户端触发它,我希望服务器这样做,即我想打开我的客户端并在服务器上输入客户端将获取数据的内容。

那么为什么我要让客户端成为客户端/服务器呢?好吧,因为我的服务器是一台机器,而我的客户端是连接服务器的XXX移动设备,这就是我实现这一点的方法。

因此,鉴于我刚才所说,我设法使用flash.net.ServerSocket 库创建了我的 AS3 客户端/服务器应用程序,该应用程序的工作方式与我想要的一样。

首先我让客户端监听:

serverSocket.bind(portNumber, "10.1.1.212");
serverSocket.addEventListener(ServerSocketConnectEvent.CONNECT, onConnectServer);
serverSocket.listen();

然后我使用flash.net.Socket Event.SOCKET_DATA 接收数据

差不多就是这样。就像我想要的那样工作。
但是,flash.net.ServerSocket 不兼容移动设备,但是...

所以这是我的问题:我需要将文件从 C# 服务器(需要监听客户端,以便我可以创建连接设备列表)发送到 AS3(AIR) 客户端,但我必须定义哪个客户端正在获取服务器上的数据,并且客户端需要随时准备接收该数据,因此,监听,但它们有很多,这就是为什么我将它们视为客户端。

我的问题是:有没有办法让客户端侦听传入连接并在发生事件时触发事件,而不使用 AS3 中的服务器套接字?

另外,如果您有不同的方法来实现我的目标而不使用 C# 服务器 AS3 客户端/服务器逻辑,请随时提出您的意见。

【问题讨论】:

    标签: actionscript-3 sockets air serversocket


    【解决方案1】:

    是的。您的客户端应该通过flash.net.Socket (doc) 或flash.net.XMLSocket (doc) 连接到服务器。在大多数情况下,您只需要一个服务器,许多客户端 可以连接到该服务器。不完全清楚为什么两端都有服务器?

    编辑:

    以下是客户端使用Socket 持续监听来自服务器的消息的快速示例。这会连接到服务器,然后(无限期地)等待数据。当接收到一大块数据时(在这种情况下,我期望字符串以换行符终止),数据将与事件一起传递。

    如果您尝试过这种方法但没有成功,您应该查看是否有任何错误或连接是否正在关闭。

    文档类:

    package  {
        import flash.display.Sprite;
    
        public class Main extends Sprite {
            protected var socket:SocketTest;
    
            public function Main() {
                this.socket = new SocketTest();
                this.socket.addEventListener(SocketMessageEvent.MESSAGE_RECEIVED, onSocketMessage);
                this.socket.connect("127.0.0.1", 7001);
            }
    
            protected function onSocketMessage(e:SocketMessageEvent):void {
                var date:Date = new Date();
                trace(date.hoursUTC + ":" + date.minutesUTC + ":" + date.secondsUTC + " Incoming message: " + e.message);
            }
        }
    }
    

    SocketTest 类:

    package  {
        import flash.net.Socket;
        import flash.events.Event;
        import flash.events.IOErrorEvent;
        import flash.events.SecurityErrorEvent;
        import flash.events.ProgressEvent;
        import flash.errors.IOError;
    
        public class SocketTest extends Socket {
            protected var _message:String;
    
            public function SocketTest() {
                super();
                this._message = "";
    
                this.addEventListener(Event.CONNECT, socketConnected);
                this.addEventListener(Event.CLOSE, socketClosed);
                this.addEventListener(ProgressEvent.SOCKET_DATA, socketData);
                this.addEventListener(IOErrorEvent.IO_ERROR, socketError);
                this.addEventListener(SecurityErrorEvent.SECURITY_ERROR, socketError);
            }
    
            protected function socketData(event:ProgressEvent):void {
                var str:String = readUTFBytes(bytesAvailable);
    
                //For this example, look for \n as a message terminator
                var messageParts:Array = str.split("\n");
    
                //There could be multiple messages or a partial message, 
                //pass on complete messages and buffer any partial
                for (var i = 0; i < messageParts.length; i++) {
                    this._message += messageParts[i];
                    if (i < messageParts.length - 1) {
                        this.notifyMessage(this._message);
                        this._message = "";
                    }
                }
            }
    
            protected function notifyMessage(value:String):void {
                this.dispatchEvent(new SocketMessageEvent(SocketMessageEvent.MESSAGE_RECEIVED, value));
            }
    
            protected function socketConnected(event:Event):void {
                trace("Socket connected");
            }
    
            protected function socketClosed(event:Event):void {
                trace("Connection was closed");
                //TODO: Reconnect if needed
            }
    
            protected function socketError(event:Event):void {
                trace("An error occurred:", event);
            }
        }
    }
    

    SocketMessageEvent 类:

    package  {
        import flash.events.Event;
    
        public class SocketMessageEvent extends Event {
            public static const MESSAGE_RECEIVED:String = "messageReceived";
    
            protected var _message:String;
    
            public function SocketMessageEvent(type:String, message:String = "", bubbles:Boolean = false, cancelable:Boolean = false) {
                super(type, bubbles, cancelable);
                this._message = message;
            }
    
            public function get message():String {
                return this._message;
            }
        }
    }
    

    作为测试,我将服务器设置为每 5 秒发送一条消息,这是控制台中的输出:

    Socket connected
    21:36:24 Incoming message: Message from server: 0
    21:36:29 Incoming message: Message from server: 1
    21:36:34 Incoming message: Message from server: 2
    21:36:39 Incoming message: Message from server: 3
    21:36:44 Incoming message: Message from server: 4
    21:36:49 Incoming message: Message from server: 5
    

    【讨论】:

    • 我已经在使用flash.net.Socket 并且可以很好地读取数据。但是接收它的触发器是在客户端上,而不是在服务器上。我搜索flash.net.XMLSocket,但没有运气。我用更多信息更新了我的主线程。
    • 我仍然看不到每个客户端都需要服务器。就像您原来的方法一样,让每个客户端建立到服务器的套接字连接 - 然后保持连接打开。让服务器跟踪连接的设备,然后它可以随时向任何连接的设备发送所需的任何数据。
    • 我试过这样做,它会触发 CONNECT 事件并停留在那里,但是当我从服务器发送包时,不会触发 SOCKET_DATA 事件。也许我错过了什么......
    • 添加了一个示例,展示了设置等待服务器发送数据的套接字连接的基础知识。
    • 您提到的方法是我尝试使用的方法,但我猜我的问题可能出在服务器上而不是客户端上。在这里你可以下载我的 C# 服务器:http://sdrv.ms/ZTu3eg 另外,你能把你的服务器代码贴出来吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 2018-02-05
    • 2015-03-01
    相关资源
    最近更新 更多