IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ActionScript 3 Discussion :

Problème de crossdomain pour Socket TCP.


Sujet :

ActionScript 3

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 5
    Par défaut Problème de crossdomain pour Socket TCP.
    Bonjour,

    je veux créer une structure évênementielle de communication TCP entre Serveur et Client.

    Je m'attaque à une chose simple pour tester la communication. J'ai l'erreur de la violation de sécurité de la Sandbox qui est due au crossdomain. Je travaille en local. J'ai un serveur NodeJS qui permet de répondre à la requête du crossdomain.

    J'ai beau chercher, je ne trouve pas ce qui cloche.

    Voici mon code :
    Serveur TCP : Main.as d'un dossier Server
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    package
    {
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.ProgressEvent;
        import flash.events.ServerSocketConnectEvent;
        import flash.net.ServerSocket;
        import flash.net.Socket;
        import flash.text.TextField;
        import flash.utils.ByteArray;
     
        public class Main extends Sprite
        {
            private var _server:ServerSocket;
    		private var _socket:Socket;
    		private var _textField:TextField;
     
    		public function Main():void
    		{
    			if(stage)
    			{
    				init();
    			}
    			else
    			{
    				this.addEventListener(Event.ADDED_TO_STAGE,init);
    			}
    		}
    		public function init(e:Event = null):void
    		{
    			_textField = new TextField();
    			_textField.width = 500;
    			_textField.height = 500;
    			addChild(_textField);
    			_server = new ServerSocket();
    			_server.bind(3336,"127.0.0.1");
    			_server.addEventListener( ServerSocketConnectEvent.CONNECT, onConnect );
    			_server.listen();
    			_textField.text = "Server Launch !\n"
    		}
     
    		public function onConnect(e:ServerSocketConnectEvent):void
    		{
    			_socket = e.socket;
    			_socket.addEventListener(ProgressEvent.SOCKET_DATA,onData);
    			_textField.appendText("New Connection : " + _socket.remoteAddress + ' : ' + _socket.remotePort + "\n");
    		}
     
    		public function onData(e:ProgressEvent):void
    		{
    			var str:String = _socket.readUTFBytes(_socket.bytesAvailable)
    			_textField.appendText("Message :" + str  + "\n");
    			_socket.flush();
    		}
        }
    }
    Client TCP : Main.as du dossier Client.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    package
    {
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.ProgressEvent;
        import flash.net.Socket;
        import flash.text.TextField;
        import flash.utils.ByteArray;
    	import flash.system.Security;
     
    	public class Main extends Sprite
    	{
    		private var _socket:Socket;
    		private var _textField:TextField;
     
    		public function Main():void
    		{
    			if(stage)
    			{
    				init();
    			}
    			else
    			{
    				this.addEventListener(Event.ADDED_TO_STAGE,init);
    			}
    		}
    		public function init(e:Event = null):void
    		{
    			_textField = new TextField();
    			_textField.width = 500;
    			_textField.height = 500;
    			addChild(_textField);
    			_socket = new Socket();
    			_socket.addEventListener(Event.CONNECT,onConnect);
    			_socket.addEventListener(ProgressEvent.SOCKET_DATA,onData);
    			_socket.connect("127.0.0.1",3336);
    		}
    		public function onConnect(e:Event):void
    		{
    			_textField.appendText("Connected\n");
    			_socket.writeUTF("bonjour");
    			_socket.flush();
    		}
    		public function onData(e:ProgressEvent):void
    		{
    			_textField.appendText("Message :" + _socket.readUTFBytes(_socket.bytesAvailable) + "\n");
    		}
    	}
     
    }
    Serveur HTTP NodeJS test.js :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    var express = require('express');
    var swig = require('swig');
    var app = express();
    var cookieParser = require('cookie-parser');
    var session = require('cookie-session');
    var bodyParser = require('body-parser');
    app.engine('html',swig.renderFile);
    app.set('view engine','html');
    app.set('views',__dirname);
    app.set('view cache', false);
    swig.setDefaults({ cache: false });
    var server = require('http').createServer(app);
    app.use(express.static(__dirname + '/web'))
    .use(cookieParser("cacaprout"))
    .use(session({secret: "cacaprout"}))
    .use(bodyParser())
    .get('/',function(req,res){
    	res.render('index');
    })
    .use(function(req,res){
    	res.redirect('/');
    })
    .listen(843);
    crossdomain.xml situé dans le répertoire web :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <?xml version="1.0"?>
    <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> 
    <cross-domain-policy> 
        <allow-access-from domain="*" to-ports="3336" /> 
    </cross-domain-policy>
    Le serveur contient tous les fichiers statiques dans le répertoire web. web est donc la racine de chaque composant statique. J'ai d'abord écouté le serveur NodeJS au port 80, puis ça n'a pas marché, j'ai vu ailleurs que la requête se faisait au niveau du port 843. Ainsi, comme le crossdomain est dans le répertoire racine des fichiers statiques, la réponse du crossdomain se fait à la requête suivante : 127.0.0.1:843/crossdomain.xml.

    J'ai vu que le client TCP faisait la requête suivante : "<policy-file-request/>" au serveur TCP du port 3336, donc la requête n'a pas marché ou n'a pas été faite au port 843. J'ai modifié mon fichier NodeJS afin de ne plus lire dans le dossier statique mais de répondre à la main d'une chaine de charactère, comme je l'ai vu dans une solution.
    Voici les modifications de test.js :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    app.use(express.static(__dirname + '/web'))
    .use(cookieParser("cacaprout"))
    .use(session({secret: "cacaprout"}))
    .use(bodyParser())
    .get('/',function(req,res){
    	res.render('index');
    })
    .get('/crossdomain.xml',function(req,res){
    	var xml = '';
    	xml += '<?xml version="1.0"?>';
    	xml += '<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> ';
    	xml += '<cross-domain-policy> ';
    	xml += '<allow-access-from domain="*" to-ports="3336" /> ';
    	xml += '</cross-domain-policy>';
    	req.setEncoding('utf8');
    	res.writeHead( 200, {'Content-Type': 'text/xml'} );
    	res.end(xml);  
    })
    .use(function(req,res){
    	res.redirect('/');
    })
    .listen(843);
    Ceci n'a eu aucun effet, la requête s'est refaite sur le serveur TCP au port 3336.

    J'ai donc voulu répondre directement à la requête par le serveur TCP et modifié mon code :
    modification du Serveur TCP Main.as :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public function onData(e:ProgressEvent):void
    {
    	var str:String = _socket.readUTFBytes(_socket.bytesAvailable)
    	_textField.appendText("Message :" + str  + "\n");
    	if(str == "<policy-file-request/>" || str == "<policy-file-request/>\0")
    	{
    		var xml:String = "";
    		xml += "<?xml version=\"1.0\"?>\n";
    		xml += "<!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">\n" ;
    		xml += "<cross-domain-policy>\n" ;
    		xml +=	"<allow-access-from domain=\"*\" to-ports=\"3336\" />\n" ;
    		xml += "</cross-domain-policy>\n";
    		_socket.writeUTF(xml);
    	}
    	else
    	{
    		_socket.writeUTF("coucou");
    	}
    	_socket.flush();
    }
    Ceci n'a eu aucun effet. J'ai eu aussi le réflexe de charger le crossdomain grâce à la classe Sécurity, bien que ça ne m'arrange pas car il faut une version récente et pour utilisateurs faire une mise à jour.

    Modification du Client TCP Main.as
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public function init(e:Event = null):void
    {
    	Security.loadPolicyFile("127.0.0.1:843/crossdomain.xml");
    //...
    Cela n'a eu aucun effet.

    En gros, je suis perdu, je ne sais pas quoi faire pour que ça marche, pouvez vous m'orienter?

    Je vous remercie d'avance pour votre réponse.

  2. #2
    Membre confirmé

    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Avril 2005
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Avril 2005
    Messages : 32
    Par défaut
    Salut !

    Je ne sais pas si tu as résolu ton problème depuis, mais pour m'être moi-même bien arraché les cheveux sur les sockets en Flash, voici mes pistes :

    Déjà, je pense que tu peux te passer de ton serveur NodeJS. Cette histoire (qu'on trouve partout sur le web et dans la doc Adobe) comme quoi Flash se connecte au port 843 pour récupérer le fichier de régulation socket... Et bien je crois que c'est juste une fable, un complot pour nous les briser, enfin ce que tu veux mais ça ne fonctionne pas, et on est nombreux à en avoir fait les frais. Tu es arrivé à la bonne conclusion, Flash se connecte directement sur le port que tu lui indique, et c'est ton serveur sur ce port qui doit lui retourner le fichier de régulation, sous forme de String.

    Donc ton avant-dernier code est celui qui devrait marcher. Il doit juste y avoir un petit couac quelque part. Personnellement, mon serveur est en Java, donc je ne suis pas familier avec les serveurs AS3, mais il fonctionne à peu près comme le tien, et ça marche. Alors :
    Déjà, quand tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var str:String = _socket.readUTFBytes(_socket.bytesAvailable)
    	_textField.appendText("Message :" + str  + "\n");
    	if(str == "<policy-file-request/>" || str == "<policy-file-request/>\0")
    	{
    Est-ce que ça marche ? Je veux dire, est-ce que c'est bien cette chaîne que le client envoie ? (sinon, recherche juste le mot "policy" dans la chaîne pour la tester, c'est peut-être un caractère qui est différent).

    Ensuite, dans ce que tu renvoie, autorise tous les ports dans un premier temps, pour tester, et surtout, met bien un caractère de fin de chaîne ("\0" ou "\u0000") à la fin : Je sais que tu fais déjà un flush, mais chez moi ça plantait sans ce caractère (Flash semble en avoir besoin).

    Voilà, force à toi et j'espère avoir pu t'aider.

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 5
    Par défaut
    Bonjour,

    tout d'abord merci de ta réponse.

    Je n'ai pas résolu le problème, j'ai tout simplement laissé tomber. J'ai fais mon serveur en NodeJS avec la librairie socket.io qui utilise un protocole de websocket, et j'ai bidouillé le client par l'intermédiaire du javascript pour communiquer et ça marche bien.

    Ceci dit, il est plus optimisé de travailler avec les socket. Et pour te dire, l'actionscript côté serveur, je ne l'utiliserai pas, la version gratuite ne me permet pas d'utiliser de base de donnée ni de lire des fichiers, de plus, je suis obligé de passer par un GUI alors pour le travail en arrière plan, c'est pas le top.

    J'ai quand même refait mes tests avec tes indications. Mon test de requête m'indique bien que la requête est policy file, donc il écrit bien le crossdomain correspondant. J'ai changé le port en * pour faire la requête sur tous les ports, j'ai rajouté \0 à la fin, ça ne marche pas. j'ai aussi remplacé par \u0000, rien à faire.

    Je suis curieux de voir ton code Java qui gère le crossdomain, car ça sera sûrement le langage que j'utiliserai pour un serveur socket. Pour le moment je fais du monothread en NodeJS, ça me suffit amplement, le serveur étant privé, je n'ai pas beaucoup de clients, mais le jour où j'aurai à gérer beaucoup de clients, il serait bien que je règle ce problème, mais ça peut attendre.

Discussions similaires

  1. [Débutant] Problème d'envoie avec Socket TCP
    Par LKThree dans le forum C#
    Réponses: 0
    Dernier message: 10/05/2013, 10h44
  2. socket TCP et temps d'attent pour une connexion?
    Par toutounesan dans le forum VB.NET
    Réponses: 28
    Dernier message: 19/08/2011, 16h51
  3. code c pour sockets (udp vers tcp et inversement)
    Par HiT dans le forum Développement
    Réponses: 11
    Dernier message: 19/11/2005, 18h03
  4. [socket][tcp] jeu en reseau
    Par souris_sonic dans le forum Développement
    Réponses: 2
    Dernier message: 30/05/2003, 07h31
  5. transfert d'un fichier bitmap en socket tcp
    Par localhost dans le forum C++Builder
    Réponses: 5
    Dernier message: 29/07/2002, 00h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo