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
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
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(); } } }
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
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"); } } }
crossdomain.xml situé dans le répertoire web :
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);
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.
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>
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 :
Ceci n'a eu aucun effet, la requête s'est refaite sur le serveur TCP au port 3336.
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);
J'ai donc voulu répondre directement à la requête par le serveur TCP et modifié mon code :
modification du Serveur TCP Main.as :
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.
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(); }
Modification du Client TCP Main.as
Cela n'a eu aucun effet.
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"); //...
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.
Partager