XML Socket and Regular Socket in Flash/Flex does not send message immediately.

Posted by kramer on Stack Overflow See other posts from Stack Overflow or by kramer
Published on 2010-03-29T20:57:58Z Indexed on 2010/04/01 10:43 UTC
Read the original article Hit count: 611

Filed under:
|
|
|
|

I am trying to build a basic RIA where my Flex application client opens an XML socket, sends the xml message "people_list" to server, and prints out the response. I have ruby at the server side and I have successfully set up the security policy stuff.

The ruby xml server, successfully accepts the connections from Flex, successfully detects when they are closed and can also send messages to client. But; there is a problem... It cannot receive messages from flex client. The messages sent from flex client are queued and sent as one package when the socket is closed. Therefore, the whole wait-for-request-then-reply thing is not working...

This is also -kinda- mentioned in the XMLSocket.send() document, where it is stated that the messages are sent async so; they may be delivered at any time in future. But; I need them to be synced, flushed or whatever.

This is the server side code:

require 'socket'
require 'observer'

class Network_Reader_Ops
    include Observable

    @@reader_listener_socket        =   UDPSocket.new
    @@reader_broadcast_socket       =   UDPSocket.new
    @@thread_id

    def initialize
        @@reader_broadcast_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1)
        @@reader_broadcast_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
        @@reader_listener_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)

        @@reader_broadcast_socket.bind('', 50050)
        @@reader_listener_socket.bind('', 50051)

        @@thread_id = Thread.start do
            loop do
                begin
                    text, sender = @@reader_listener_socket.recvfrom_nonblock 1024
                    print("Knock response recived: ", text)
                    notify_observers text
                rescue Errno::EAGAIN
                    retry
                rescue Errno::EWOULDBLOCK
                    retry
                end
            end
        end
    end

    def query
        @@reader_broadcast_socket.send("KNOCK KNOCK", 0, "255.255.255.255", 50050)
    end

    def stop
        Thread.kill @@thread_id
    end
end

class XMLSocket_Connection
    attr_accessor :connection_id

    def update (data)
        connection_id.write(data+"\0")
    end
end

begin
    # Set EOL for Flash
    $/ = '\x00'

    xml_socket                  =   TCPServer.open('', '4444')
    security_policy_socket      =   TCPServer.open('', '843')

    xml_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
    security_policy_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)

    a = Thread.start do
        network_ops = nil
        loop {
            accepted_connection = xml_socket.accept
            print(accepted_connection.peeraddr, " is accepted\n")

            while accepted_connection.gets
                incoming = $_.dump
                print("Received: ", incoming)
                if incoming == "<request>readers on network</request>" then
                    network_ops = Network_Reader_Ops.new
                    this_con = XMLSocket_Connection.new
                    this_con.connection_id = accepted_connection
                    network_ops.add_observer this_con
                    network_ops.query
                end
            end

            if not network_ops.nil? then
                network_ops.delete_observer this_con
                network_ops.stop
                network_ops = nil
            end
            print(accepted_connection, " is gone\n")
            accepted_connection.close
        }
    end

    b = Thread.start do
        loop {
            accepted_connection = security_policy_socket.accept

            Thread.start do
                current_connection = accepted_connection
                while current_connection.gets
                    if $_ =~ /.*policy\-file.*/i then
                        current_connection.write("<cross-domain-policy><allow-access-from domain="*" to-ports="*" /></cross-domain-policy>\0")
                    end
                end
                current_connection.close
            end
        }
    end

    a.join
    b.join
rescue
    puts "FAILED"
    retry
end

And this is the flex/flash client side code: UPDATE: I have also tried using regular socket and calling flush() method but; the result was same.

        private var socket:XMLSocket = new XMLSocket();
        protected function stopXMLSocket():void
        {
            socket.close();
        }


        protected function startXMLSocket():void
        {
            socket.addEventListener(DataEvent.DATA, dataHandler);
            socket.connect(xmlSocketServer_address, xmlSocketServer_port);
            socket.send("<request>readers on network</request>");
        }

        protected function dataHandler(event:DataEvent):void
        {
            mx.controls.Alert.show(event.data);
        }

How do I achieve the described behaviour?

© Stack Overflow or respective owner

Related posts about flex

Related posts about xmlsocket