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
Était-ce utile?

La 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 .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top