Results 1 to 12 of 12

Thread: Inqueries for CL_NetGame

  1. #1
    Lesser Wizard
    Join Date
    Jun 2007
    Posts
    109

    Default Inqueries for CL_NetGame

    Trying to consolidate my "ask a developer" about the new clan lib networking here, I hope you guys don't mind! It's nice to converse with the folks who wrote this because who knows better than them?

    This is sort of a design question about using the NetGame API in a real world, larger scale situation than the demo.

    Does the NetGame system automatically handle events and their callbacks in the order received? Should I be handling event responses from the callbacks in a higher level way (containers), or is that mis-using the simplicity and auto-magic nature of the system?

    I was concerned about lower-pinging clients getting more out of the server than more delayed connections (which is always a problem, but order of events is most important for me in my design).

    So what I'm kind of doing right now is this (psuedo-ish code):

    Code:
    main()
    
    while(!done)
    
       ...
    
       network.process_events();
       objects.simulate(delta_time);
       objects.draw(gc); // <--- client only
       ...

    I think being somewhat familiar with the older netsession API, I'm a little hesitant to handle things immediately when I get them in the callback. Since, if I recall, the older system was run on it's own separate thread, so handling things at the moment of reception could lead to out of order processing or non thread-safe code (this was well over a year ago, forgive me if I'm wrong).

    While coding my little project, I found myself reluctant to toss back immediate send_event within the call back function (as the demo does), because I thought that was handling things out of order. But it seems by calling process_events() that's essentially ClanLib running through it's own internal queue of network traffic it received since the last update, correct?

    So I guess what I'm asking is if it's "okay" to deal with events in the call back function, or should I be diverting that to yet another container (which seems wasteful if it works how I think it does). So that's what I need help on. Am I thinking it works how it does, or am I not?

    Lovely little system though, you've all really outdone yourselves this time. And forgive me for all the questions, but it's very intriguing to me, and I just want to use it to the fullest potential.


    Thanks,
    Dan

  2. #2
    ClanLib Developer
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    554

    Default

    The events are received in exactly the order they are sent.

    The events are dispatched to the handlers during the call to process_events() and not in the worker threads that handles the actual network communication. Any processing in the callbacks are therefore completely thread safe because they run in the game thread.

    You can therefore safely react on the events in the callbacks.

    As for multiple clients, the server queues the messages up for each individual client - so a low ping client will receive the events sooner than a high ping client. But the order of the events sent to a client will always be the same.

    Hope that answers your questions.

  3. #3
    Lesser Wizard
    Join Date
    Jun 2007
    Posts
    109

    Default

    Excellent. That's surprisingly simple.

    THANKS!


    Edit: the only other thing I could think of right now is marshaling and maybe using the add_argument feature to do a quasi-mashaling scheme. I was either going to do a semi-colon spaced string containing a large number of objects to update (and take it apart and make sense of it on the client side), but maybe I could just use the add_argument feature to do just that.

    Is there any particular downside to adding like 20-40 arguments to a net event? I know the packet size would get larger, but I'd be planning on doing my own ~300byte string and sending it along anyhow.

    This way, if changes to clan lib are ever made for optimization, it'd be automatic for me rather than having to worry about compressing my own strings (which I should stop being a slacker right? lol)

    *ponders if sizeof() will work on CL_NetGameEvent values...*
    Last edited by catch22; 06-09-2009 at 07:08 PM.

  4. #4
    ClanLib Developer
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    554

    Default

    Yes, you can simply use add_argument 40 times.

  5. #5
    ClanLib Developer
    Join Date
    Sep 2006
    Location
    Bergen, Norway
    Posts
    588

    Default

    FYI, I almost only use add_parameter in my project

    Btw, here is some of the code I use for network activity tracking:

    Code:
    #pragma once
    
    class NetworkActivity : public CL_NetGameEventDispatcher_v0
    {
    public:
        NetworkActivity() : total_packet_count(0), total_packet_size(0), latency(0)
        {
            func_event("Pong").set(this, &NetworkActivity::on_event_pong);
        }
    
        unsigned int get_total_packet_count() const { return total_packet_count; }
        unsigned int get_total_packet_size() const { return total_packet_size; }
        unsigned int get_latency() const { return latency; }
    
        void on_event_pong(const CL_NetGameEvent& e)
        {
            int originalTime = e.get_argument(0);
            int time = CL_System::get_time();
    
            latency = time - originalTime;
        }
    
        void on_event_received(const CL_NetGameEvent& e)
        {
            unsigned int packetSize = 0;
            unsigned int argument_count = e.get_argument_count();
            for(size_t i = 0; i < argument_count; ++i)
            {
                CL_NetGameEventValue eventValue = e.get_argument(i);
                packetSize += eventValue.get_value().length();
            }
    
            total_packet_count++;
            total_packet_size += packetSize;
        }
    
    private:
        unsigned int total_packet_count;
        unsigned int total_packet_size;
        unsigned int latency;
    };
    and somewhere else:
    Code:
    {
        ....
    
        slots.connect(networkClient.sig_event_received(), &networkActivity, &NetworkActivity::on_event_received);
    
        ....
    
        timer.start(1000);
        timer.func_expired().set(this, &Client::OnTimer);
        OnTimer();
    
        ....
    }
    
    void Client::OnTimer()
    {
        networkClient.send_event(CL_NetGameEvent("Ping", CL_System::get_time()));
    }
    And on the server side you need to respond to the Ping event, and do something like:
    Code:
    void Server::OnEventPing(const CL_NetGameEvent& e, CL_NetGameConnection* connection)
    {
        int time = e.get_argument(0);
        connection->send_event(CL_NetGameEvent("Pong", time));
    }
    Now, you can use the NetworkActivity class, create some GUI view of it, and query for packet count, packet sizes, and latency. Note that the packet sizes is not taking into account the protocol overhead, it only includes the size of the actual data sent.
    Last edited by sphair; 06-12-2009 at 10:35 PM.

  6. #6
    Lesser Wizard
    Join Date
    Jun 2007
    Posts
    109

    Default

    Nice! Thanks for sharing that.

  7. #7
    Lesser Wizard
    Join Date
    Jun 2007
    Posts
    109

    Default

    Bump on a related note:

    With the old networking stuff being phased on (netsession and what not)... is there a ClanLib way to do remote file downloading?

    Like the server has a skin file and wants to share it with the client... I had written a worker thread for the old clan lib that would download small files.

    Could the HTTP stuff be used for that now?

  8. #8
    ClanLib Developer
    Join Date
    May 2007
    Posts
    1,824

    Default

    We do have:

    CL_TCPConnection : public CL_IODevice

    Since it inherits CL_IODevice, this can be used for loading ClanLib data

    At the moment, we do not have a CL_VirtualFileSystem for the network classes.

    Disclaimer:
    This is by looking at the API, I have not tried it, I could be wrong

  9. #9
    Lesser Wizard
    Join Date
    Jun 2007
    Posts
    109

    Default

    Quote Originally Posted by rombust View Post
    We do have:

    CL_TCPConnection : public CL_IODevice

    Since it inherits CL_IODevice, this can be used for loading ClanLib data

    At the moment, we do not have a CL_VirtualFileSystem for the network classes.

    Disclaimer:
    This is by looking at the API, I have not tried it, I could be wrong
    Sorry to bump an old thread, but do you think this would still work?

    Any plans from the developers to handle remote files or will this method work... in theory?

  10. #10
    ClanLib Developer
    Join Date
    May 2007
    Posts
    1,824

    Default

    afaik, the active developers will not be looking into it.

    It's difficult to say if it is possible, without actually trying implementing it.

    Have a look at Development\ClanLib-2.2\Tests\Network\HttpFileUpload ... it may be useful

  11. #11

    Default

    Hi Sphair,

    In the network activity tracking code above, I'm getting a non-member compile error in 2.2.5 on this line:

    packetSize += eventValue.get_value().length();

    I don't see get_value() or length() defined in any of the event_value.h or other headers I've looked at.

    I can do eventValue.get_member() but it's looking for an index to something....I'm not sure to what or how anything is indexed. Can you shed some light here please?

    Many thanks!

  12. #12
    ClanLib Developer
    Join Date
    Sep 2006
    Location
    Bergen, Norway
    Posts
    588

    Default

    I guess the API was changed, so this is no longer possible to do.

Bookmarks

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •