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.