Question

Hey I'm working in project, but i cant manage to connect from a IP not located in the same network (LAN). The code bellow works fine locally, but I cant figure out how to make work from different IP located in different locations?, and google cant see to help, any ideas?

   class
    RG_NETWORK_SERVER

inherit
    STORABLE
    NETWORK_SERVER
        redefine
            receive,
            received,
            close
        end

create
    make_server

feature
    connections: LINKED_LIST [RG_CONNECTION]
    max_to_poll: INTEGER
    message_out: RG_MESSAGE
    received: detachable RG_MESSAGE
    poll: MEDIUM_POLLER

    make_server
        require

        local
            l_message_out: detachable like message_out
            l_connections: detachable like connections
            l_in: detachable like in
        do
            make (1337)
            max_to_poll := 1
            create poll.make_read_only
            in.set_non_blocking
            l_in := in
            create l_message_out.make
            message_out := l_message_out
            create l_connections.make
            connections := l_connections
            connections.compare_objects
            execute
        end

    process_message
        local
            stop: BOOLEAN
            pos: INTEGER
        do
            from
                connections.start
            until
                connections.after or stop
            loop
                if connections.item.is_waiting then
                    if attached {RG_MESSAGE} retrieved (connections.item.active_medium) as l_message_in then
                        if l_message_in.new then
                            connections.item.set_client_name (l_message_in.client_name)
                            create message_out.make
                            message_out.set_client_name (l_message_in.client_name)
                            message_out.extend (l_message_in.client_name)
                            message_out.extend (" has just joined the server%N")
                        elseif l_message_in.over then
                            poll.remove_associated_read_command (connections.item.active_medium)
                            connections.remove
                            create message_out.make
                            message_out.set_client_name (l_message_in.client_name)
                            message_out.extend (l_message_in.client_name)
                            message_out.extend (" has just gone%N")
                            stop := True
                        else
                            message_out := l_message_in.deep_twin
                            message_out.put_front (" has just sent that :%N")
                            message_out.put_front (message_out.client_name)
                            message_out.put_front ("-> ")
                        end
                        pos := connections.index
                            -- l_message_in.print_message
                        message_out.print_message
                        broadcast
                        connections.go_i_th (pos)

                            -- Post status to client
                        create message_out.make
                        message_out.extend ("Got it! %N")
                        message_out.independent_store (connections.item.active_medium)
                    end
                end
                if not stop then
                    connections.forth
                end
            end
        end

    broadcast
        local
            client_name: detachable STRING
        do
            client_name := message_out.client_name
            if client_name /= Void then
                from
                    connections.start
                until
                    connections.after
                loop
                    if connections.item.client_name /~ client_name then
                        message_out.independent_store (connections.item.active_medium)
                    end
                    connections.forth
                end
            end
        end

    receive
        do
            in.accept
            if attached {like outflow} in.accepted as l_outflow then
                l_outflow.set_blocking
                new_client (l_outflow)
            end
            from
                connections.start
            until
                connections.after
            loop
                connections.item.initialize
                connections.forth
            end
            poll.execute (max_to_poll, 1000)
        end

    new_client (a_flow: attached like outflow)
        local
            new_connection: RG_CONNECTION
        do
            if max_to_poll <= a_flow.descriptor then
                max_to_poll := a_flow.descriptor + 1
            end
            create new_connection.make (a_flow)
            connections.extend (new_connection)
            create message_out.make
            message_out.extend ("Welcome! %N")
            message_out.independent_store (a_flow)
            poll.put_read_command (new_connection)
        end

end

and the client:

class
    RG_NETWORK_CLIENT

inherit
    NETWORK_CLIENT
        redefine
            received
        end

create
    make_join

feature
    make_join(ip:STRING)
        require
            is_ip_void : ip /= Void
        local
        l_client_name: detachable like client_name
        do
            check_name
            l_client_name := client_name
            make (1337, ip)
            max_to_poll := in_out.descriptor + 1
            create connection.make (in_out)
            create poll.make_read_only
            poll.put_read_command (connection)
            send_name_to_server
            auto_scan_server
            processing
        end

feature

    connection: RG_CONNECTION
    std_input: detachable RG_CONNECTION
    message_out: RG_MESSAGE
    received: detachable RG_MESSAGE
    client_name: STRING
    over: BOOLEAN
    poll: MEDIUM_POLLER
    input_poll: detachable MEDIUM_POLLER
    max_to_poll: INTEGER
    waiting:BOOLEAN

    send_name_to_server
        do
            create message_out.make
            message_out.set_client_name (client_name)
            message_out.set_new (True)
            message_out.set_over (False)
            send (message_out)
        end

    processing
        do
            from
                over := False
            until
                over
            loop
                scan_from_server
                if not over then
                    read_content
                end
            end
            cleanup
        end

    read_content
        local
            temp: detachable STRING
        do
            io.put_string ("Enter message: ")
            io.readline
            temp := io.laststring
            if temp /= Void and not temp.is_empty then
                if temp.is_equal ("bye") then
                    over := True
                end
                create message_out.make
                message_out.extend (temp)
                message_out.extend ("%N")
                message_out.set_over (over)
                message_out.set_client_name (client_name)
                message_out.set_new (False)
                send (message_out)
                auto_scan_server
            end
        end

    check_name
        local
            l_name: detachable STRING
        do
            io.putstring ("Enter your name : ")
            io.readline
            l_name := io.laststring
            check
                l_name_attached: l_name /= Void
            end
            client_name := l_name.twin
        end

    scan_from_server
        local
            l_received: like received
        do
            connection.initialize
            poll.execute (max_to_poll, 1000)
            if connection.is_waiting then
                receive
                l_received := received
                if l_received /= Void then
                    waiting := FALSE
                    l_received.print_message
                    if l_received.over then
                        over := True
                    end
                end
            end
        end

    auto_scan_server
        do
            waiting := True
            from until not waiting
            loop
                scan_from_server
            end
        end

end
Was it helpful?

Solution

The work around is the work with the samples provided from Eiffel, it works as longest the two persons are connected in the same network. for example as follow:

Here we define if the user has receive the message or is waiting for one, also redefine the poll_command to be able to use it.

inherit

    POLL_COMMAND
        redefine
            make
        end

create
    make

feature {NONE} -- Initialization

    make (s: IO_MEDIUM)
        do
            Precursor (s)
            create client_name.make_empty
        end

feature

    is_waiting: BOOLEAN
    client_name: STRING

    execute (arg: ANY)
        do
            is_waiting := True
        end

    initialize
        do
            is_waiting := False
        end

    set_client_name (s: STRING)
        require
            s_exists: s /= Void
        do
            client_name := s.twin
        end

end 

Then following the chat sample, that can be found in the samples folder, in the message handler, we create the follow:

set_client_name (s: STRING)
        require
            s_not_void: s /= Void
        do
            client_name := s.twin
        end

    set_new (flag: BOOLEAN)
        do
            new := flag
        end

Later in the connection class we are able to connect to a server ip, which it can be pass true command line or via GUI input.

make_join (name: STRING; ip: STRING; gc: RG_CLIENT)
        require
            is_ip_void: ip /= Void
        do
                -- Connects to IP on port 1337
            make (1337, ip)
            max_to_poll := in_out.descriptor + 1
            create connection.make (in_out)
            create poll.make_read_only
            poll.put_read_command (connection)
                -- Sets client name and refrence
            client_name := name
            p_client := gc
                -- Sends name to server and receives ID
            client_id := send_name_to_server
                -- Launches instance as thread
            make_thread
            launch
            execute
        end

Then in the server class...

make_server (gs: RG_SERVER)
        local
            l_message_out: detachable like message_out
            l_connections: detachable like connections
            l_in: detachable like in
        do
                -- Instantiate reference and create server listening on port 1337
            game_server := gs
            make (1337)
            max_to_poll := 1
            create poll.make_read_only
            in.set_non_blocking
            l_in := in
            create l_connections.make
            connections := l_connections
            connections.compare_objects
                -- Launches instance as tread
            make_thread
            launch
        end

There is a bit more code, but this is a good sample in how to do it, there must be a method to handle the connections, but this is a good start, also remember that all this is based on their samples, chat sample is a good point of start..

enjoy eiffel while is not crashing .

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top