AIR 2 ServerSocket的跨域问题问题、AIR、ServerSocket

2023-09-08 13:45:57 作者:野的像风

我愿通过ServerSocket类的AIR 2服务器(你会发现code以下关于它的一个例子)。

约束:

服务器必须在空气 在客户端必须通过Web浏览器显示

客户端显示与Web浏览器,所以当客户想建立空服务器的连接,闪光灯发出跨域请求通过socket和服务器发回,但没有hapen呢。

该As3Doc指定,当闪光灯发出跨域请求,服务器必须回送,则Flash将关闭连接,并打开一个新的连接,如果跨域是确定的。

我尝试过不同的设置,但没有任何工程,客户端永远不会接收关连的事件。

任何想法?

服务器端code:

 < XML版本=1.0编码=UTF-8&GT?;
< S:的WindowedApplication的xmlns:FX =htt​​p://ns.adobe.com/mxml/2009
                       XMLNS:S =库://ns.adobe.com/flex/spark
                       的xmlns:MX =库://ns.adobe.com/flex/mx初始化=的init()>

    &所述氏:文本X =0Y =0的宽度=100%高度=100%的id =登录/>

    < FX:脚本>
        <![CDATA [
            私人VAR _ SERVER:ServerSocket的=新的ServerSocket;

            私有函数的init():无效
            {
                _server.bind(4500,127.0.0.1);
                _server.addEventListener(ServerSocketConnectEvent.CONNECT,onClientConnection);
                _server.listen();
            }

            私有函数onClientConnection(E:ServerSocketConnectEvent中):无效
            {
                VAR套接字:socket = e.socket;
                log.appendText(客户端连接:+ socket.localAddress +:+ socket.localPort +\ N);
                socket.addEventListener(ProgressEvent.SOCKET_DATA,昂达);
            }

            私有函数昂达(五:事件):无效
            {
                VAR套接字:socket = e.target的插座;
                log.appendText(数据:+ socket.readUTFBytes(socket.bytesAvailable));
                socket.writeUTF(
                    <交领域的政策和GT; +
                    '<允许存取来自域=*到端口=4500/> +
                    '< /跨域策略>
                    + String.fromChar code(0)
                    );
                socket.writeByte(0);
                socket.flush();
                socket.close();
            }
        ]]≥
    < / FX:脚本>
&所述; /秒:的WindowedApplication>
 

客户端code:

 包
{
    进口flash.display.Sprite;
    进口对象类型:flash.events.Event;
    进口flash.events.IOErrorEvent在;
    进口flash.events.SecurityErrorEvent;
    进口flash.net.Socket;
    进口API元素flash.text.TextField;
    进口flash.utils.setTimeout;

    公共类TestClient的扩展Sprite
    {
        私人VAR日志:文本字段;
        私人VAR _socket:插座;

        公共职能TestClient的()
        {
            登录=新的TextField;
            log.width = stage.stageWidth;
            log.height = stage.stageHeight;
            的addChild(日志);

            _socket =新的Socket;
            _socket.addEventListener(Event.CONNECT,的OnConnection);
            _socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,onError的);
            _socket.addEventListener(IOErrorEvent.IO_ERROR,onError的);
            tryConnection();
        }

        私有函数tryConnection():无效
        {
            log.appendText(尝试连接... \ N);
            _socket.connect(127.0.0.1,4500);
        }

        私有函数的OnConnection(五:事件):无效
        {
            log.appendText(保持通话!);
        }

        私有函数的onError(五:事件):无效
        {
            log.appendText(e.toString()+\ N);
            的setTimeout(tryConnection,1000);
        }
    }
}
 

解决方案

你的做法是对的,但你使用 writeUTF 写下XML策略文件中的插座。 writeUTF 实际UTF字符串之前还写入字符串的两个字节的长度。这是破坏XML策略文件中的客户端接收。

只需使用 writeUTFBytes 而不是 writeUTF ,一切都应该工作得很好。

另外,你不需要 writeByte 像你一样。追加一个字符的字符串政策就足够了。

分布式系统下session跨域问题综合解决方案3

I wish to make an Air 2 Server via ServerSocket class (you will find below code an example about it).

Constraints :

Server must be in Air Client must be displayed through web browser

Clients are displayed with an Web browser so when a client want to establish a connection to Air server, Flash sends a crossdomain request through socket and server sends it back but nothing hapen then.

The As3Doc specifies that when flash sends crossdomain request, server must to send it back, then Flash closes connection and open a new connection if crossdomain is ok.

I've tried different settings but nothing works, client never receives CONNECTED's event.

Any ideas ?

Server side code :

<?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" initialize="init()">

    <s:TextArea x="0" y="0" width="100%" height="100%" id="log"/>

    <fx:Script>
        <![CDATA[
            private var _server : ServerSocket = new ServerSocket;

            private function init() : void
            {
                _server.bind(4500, "127.0.0.1");
                _server.addEventListener(ServerSocketConnectEvent.CONNECT, onClientConnection);
                _server.listen();
            }

            private function onClientConnection(e : ServerSocketConnectEvent) : void
            {
                var socket : Socket = e.socket;
                log.appendText("Client connected : " + socket.localAddress + ":" + socket.localPort + "\n");
                socket.addEventListener(ProgressEvent.SOCKET_DATA, onData);
            }

            private function onData(e:Event) : void
            {
                var socket : Socket = e.target as Socket;
                log.appendText("Data : " + socket.readUTFBytes(socket.bytesAvailable));
                socket.writeUTF(
                    '<cross-domain-policy>' +
                    '       <allow-access-from domain="*" to-ports="4500" />' +
                    '</cross-domain-policy>'
                    + String.fromCharCode(0)
                    );
                socket.writeByte(0);
                socket.flush();
                socket.close();
            }
        ]]>
    </fx:Script>
</s:WindowedApplication>

Client side code :

package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.Socket;
    import flash.text.TextField;
    import flash.utils.setTimeout;

    public class TestClient extends Sprite
    {
        private var log : TextField;
        private var _socket : Socket;

        public function TestClient()
        {
            log = new TextField;
            log.width = stage.stageWidth;
            log.height = stage.stageHeight;
            addChild(log);

            _socket = new Socket;
            _socket.addEventListener(Event.CONNECT, onConnection);
            _socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
            _socket.addEventListener(IOErrorEvent.IO_ERROR, onError);
            tryConnection();
        }

        private function tryConnection() : void
        {
            log.appendText("Try connection ... \n");
            _socket.connect("127.0.0.1", 4500);
        }

        private function onConnection(e : Event) : void
        {
            log.appendText("Connected !");
        }

        private function onError(e : Event) : void
        {
            log.appendText(e.toString() + "\n");
            setTimeout(tryConnection, 1000);
        }
    }
}

解决方案

Your approach is right, but you're using writeUTF to write down the XML policy file to the socket. writeUTF also writes the length of the string in two bytes before the actual UTF string. That is corrupting the XML policy file the client is receiving.

Simply use writeUTFBytes instead of writeUTF and everything should work just fine.

Also, you don't need to writeByte like you do. Appending a null character to your policy string is enough.