1

I have a socket server listening on 2 ports, 1 port for the socket server and 1 port for the policy server.

My code is below, in this scenario, data is sent and received perfectly fine. however, for example if I add a button with a simple:

socket.writeUTFBytes("Message"); socket.flush();

after the initial connection, it doesn't seem to send any data to my server (I have my server printing all data transmissions to the console for checking) Initial connections work fine, as seen below:

//authenticate with socket server first: var xmlSocket = new XMLSocket(); xmlSocket.connect("192.xx.xx.xx", 843);

try {
    Security.loadPolicyFile("xmlsocket://192.xx.xx.xx:843");
} catch (e:IOError) {
    //tbOutput.text += e.text;
}


var socket:Socket = new Socket();
socket.addEventListener(Event.CONNECT, onConnect);
socket.addEventListener(Event.CLOSE, onClose);
socket.addEventListener(IOErrorEvent.IO_ERROR, onError);
socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecError);

try {
socket.connect("192.xx.xx.xx", 4444);
} catch (e:IOError) {
    //error traced
}


function onConnect(e:Event):void {
    //initial message to socket server:
    var Message:String;
    //message contains something
    socket.writeUTFBytes(Message.toString() + "<EOF>");
    socket.flush();

    }

MWard
  • 135
  • 2
  • 6
  • 15

1 Answers1

3

You basically have it right you just missed something.
The initial connection is saved for the crossdoamin file even is you specify another port it will try to get the file from 4444 first and if that fails then it will go for the master on the default port(843).
Here is your offending line

Security.loadPolicyFile("xmlsocket://192.xx.xx.xx:843");

If you look at your server logs you will find that when the first connection was made there was a request in the form of <policy-file-request/> made to the server.
Once that request is completed and the file delivered to the client then the connection will be closed by the client always.
On the client side once the crossdomain is received and the connection closed you can then reconnect and send at will.


So to recap.
Your flash app made a connection to the server.
Then your app requested the crossdomain and sat and waited
Before the connection timed out you then proceeded to send data of some sort over your the connection
The app still waiting for the cross domain received a response from your server
Since the data received from the server is not the crossdomain.xml file your app closed the connection and will not allow reconnects

I changed your code a bit to auto reconnect
However your server on port 4444 should return the crossdomain file when there is a request for it.

try {
  Security.allowDomain('192.xx.xx.xx');
  Security.loadPolicyFile("xmlsocket://192.xx.xx.xx:4444");
} catch (e:IOError) {
    //tbOutput.text += e.text;
}


var socket:Socket = new Socket();
socket.addEventListener(Event.CONNECT, onConnect);
socket.addEventListener(Event.CLOSE, onClose);
socket.addEventListener(IOErrorEvent.IO_ERROR, onError);
socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecError);

function connect( ){
  if( !socket.connected ){
    try {
      socket.connect("192.xx.xx.xx", 4444);
    } catch (e:IOError) {
      //error traced
    }
  }
}

function onConnect(e:Event):void {
    //initial message to socket server:
    var Message:String;
    //message contains something
    //socket.writeUTFBytes(Message.toString() + "<EOF>");// EOF bad
    socket.writeUTFBytes(Message.toString() + String.fromCharCode(0) ); // NULL good
    socket.flush();

}

function onResponse(e:ProgressEvent):void {
  var read:String = this.readUTFBytes(this.bytesAvailable );

  // I test for a < since my server will never return a "<" as the first character
  // unless it is the crossdomain.xml file
  // you may need to change this for your needs
  if( read.charAt(0) !='<' ){
    if( read ){
      // so something with your response
    }
  }else{
    // recieved crossdomain policy nothing to really do here it is handled internally
  }
}


var connectTimer:Timer = new Timer( 1000 );
connectTimer.addEventListener(TimerEvent.TIMER, connect );
connectTimer.start();

Don't forget for this to work your server on port 4444 needs to return the crossdomain file on that port

The_asMan
  • 6,364
  • 4
  • 23
  • 34
  • Sorry for the delay in replying to this help, the project took a few turns for the worse and I had to wait until I came back to it!. I have since moved the crossdomain request onto the main port and handled it as so: http://pastebin.com/J33Mzk1q It is a little messy but I just want to see things working!. I still have the original problem, my flash application can send and recieve data once, but any other "socket.writeUTFBytes("Message"); socket.flush();" nothing is captured on the server – MWard Sep 20 '11 at 15:24
  • On your server in ReadCallBack you are not handling (!bytesRead > 0) This is where the client disconnects. Try putting some debug code there you will see it is being triggered. – The_asMan Sep 20 '11 at 15:55
  • 1
    change out "" to String.fromCharCode(0) the server will read until it sees a null character or untill buffer is full. So if you are passing large amounts of data you have to loop the read. – The_asMan Sep 20 '11 at 16:04
  • what should I put into the (!bytesRead > 0) condition? I basically want to prepare the server for any other incomming data? – MWard Sep 20 '11 at 18:37
  • The_asMan, thank you so much for mentioning , I had a issue in my experiment and that was exactly what I was missing! :) – chamberlainpi Mar 07 '13 at 06:45
  • Although port 4444 is widely used in examples, it has proved a poor choice in the wild for us as it clashes with web proxies for users on certain ISPs. Use of port numbers 49152–65535 is more reliable. – Dave Walker Jul 15 '13 at 16:47