I'm trying to use Cap’n Proto in existing project consisting of client and server communicating over UDS. I don't have the resources (and I doubt it would be accepted) to redo all client-server RPC, but I wanted to benefit from Cap’n Proto serialization mechanisms. Unfortunately, it seems to me it's impossible.
The biggest problem is server side, which is single threaded (and it will remain so, if there aren't any serious arguments for multithreading) and uses it's own poll based loop. All events are read partially, server can't block waiting for any event to be fully read - and this is where I am stuck. We have our own protocol and classes which wrap the message, which can consume bytes from file descriptor and notify, when the event is fully read, so the server can process it. I think I've analysed most of Cap’n Proto interfaces (serialization, async serialization) and it seems, that it can't be used the same way without any modifications.
I really hope that I've missed something. Did I?
There are two ways you can solve this:
Hard way: You can attempt to integrate with the KJ async I/O framework (used by Cap'n Proto). The KJ event loop can actually integrate with other event loops and run on top of them -- but it's tricky. For example, node-capnp includes code to integrate the KJ event loop with libuv, as seen in the first part of this source file. Once you have the necessary glue, you can write KJ-style async code that uses the interfaces in capnp/serialize-async.h.
Easy way: Instead of trying to integrate KJ, you can write simple code using your event infrastructure which reads data from the file descriptor directly and then uses capnp::expectedSizeInWordsFromPrefix() (from capnp/serialize.h) to figure out if it has received the whole message yet. If that function returns a number greater than what you already have, then you don't have the full message and have to keep waiting. Once you have the full message, you can then use capnp::FlatArrayMessageReader to parse it.
Related
I have been reading through the boost asio documentation for a couple of hours now, and while I think the documentation is really great, I am still left a bit confused on how to implement the system that I need.
I have to stream info, from a game engine, to a list of computers over tcp. One snag is that, unlike traditional pub/sub, the computer that does the distribution of info is actually the computer that has to connect to the subscribers as well (instead of the subscribers registering with the publisher). This is done via a config file - a list of ip's/ports along with the data that they each require. The subscribers listen, but do not know the ip of the publisher. (As a side note, I'm quite new to network programming, so maybe I'm missing something .. but it's strange that I do not find much information regarding this style of "inverted" client-server model..)
I am looking for suggestions for the implementation of such a system using boost asio. Of course I have to integrate the networking into an already existing engine, so with regards to that:
What would be a good way to handle messages being sent to multiple computers every frame? Use async_write, call io_service.run and then reset every frame? Would having io_service.run have its own thread be better? Or should I just use threads and use blocking writes?
I found a thread which deals with part of my question: using io_service within a game loop -Boost::Asio : io_service.run() vs poll() or how do I integrate boost::asio in mainloop. I will try a few things and post a more definite answer if I do find a good solution.
My situation: I would like to create a hobby project for improving my C++ involving real-time/latency programming.
I have decided I will write a small Java program which will send lots of random stock prices to a client, where the client will be written in C++ and accept all the prices.
I do not want the C++ client to have to poll/have a while loop which continuously checks for data even if there is none.
What options do I have for this? If it's easier to accomplish having a C++ server then that is not a problem.
I presume for starters I will have to use the boost ASIO package for networking?
I will be doing this on windows 7.
Why not just have the Java server accept connections and then wait for some duration of time. e.g. 10 seconds. Within that time if data becomes available, send it and close the connection.
Then the C++ client can have a thread which opens a connection whenever the previous one has completed.
That should give quite low latency without creating connections very often when there is no new data.
This is basically the Comet web programming model, which is used for many applications.
Think about how a web server receives data. When a URL is accessed the data is pushed to the server. The server need not poll the client (or indeed know anything about the client other than its a service pushing bytes towards it).
You could use a Java servlet to accept the data over HTTP and write the code in this fashion. Similarly, boost::asio has a server example that should get you started. Under the hood, you could enable persistent HTTP so that the connections aren't opened / closed frequently. This'll make the coding model much simpler.
I do not want the C++ client to have to poll/have a while loop which
continuously checks for data
Someone HAS to.
Need not be you. I've never used boost ASIO, but it might provide a callback registration. If yes, then just register a callback function of yours with boost, boost would do the waiting and give you a call back when it gets some data.
Other option is of course that you use some functions which are synchronous. Like (not a real function) Socket.read() which blocks the thread until there is data in the socket or it's closed. But in this case you're dedicating a thread of your own.
--edit--
Abt the communication itself. Just pick any IPC mechanism (sockets/pipes/files/...), someone already described one I think. Once you send the data, the data itself is "encoded" and "decoded" by you, so you can create your own protocol. E.g. "%%<STOCK_NAME>=<STOCK_PRICE>##" where "%%", = and ## (markers to mark start, mid and end) that you add on sender side and remove on receiver side to get stock name and price.
You can develop the protocol further based on your needs. Like you can also send buy/sell recommendation or, text alert msgs with major stock exchange news. As long as your client and server understand how the data is "encoded" you're good.
Finally, if you want to secure teh communication (and say you're not using some secure layer (SSL)) then you can encrypt the data. But that's a different chapter. :)
HTH
I'm working on a little client that interfaces with a game server. The server sends messages to the connected client over HTTP. Its relatively easy to parse the text messages coming into the client and form responses to send back.
Now what I'm trying to figure out is how to break up the process. I want to have a thread receiving the messages, parsing them into some data object, and placing them into an "incoming" queue to be processed. Then another thread reads messages from this queue and processes them (the brains or AI of the client) and makes responses back to the server.
I want to have the thread that watches the incoming data to do process the text (break up the messages, pull the important data out, etc.) so the AI thread doesn't have that overhead. But the problem is that the server can send a couple hundred different types of messages to the client (what the client can see, other players, if you are firing etc). I want to package this data into a neat little structure so the AI can handle it quickly, and the AI can be rewritten easily.
But how do I write a function that can pull something off a queue and know what type of message it is (so I know what data is contained within the message)?
Example messages:
ALIVE (tells you if you are alive)
It has only one data object, the current game time
DAM (tells if you are damaged)
Has a whole bunch of data, who damaged you, how much, what gun it is, if you can see them, etc.
It is possible to make an object that can handle all of these different message types and be interpreted by a single function? Very few messages have common attributes, so I don't think inheriting or just making one really big message class would be very good...
I'm not looking for a full solution here, just point me in the right direction and hopefully I'll be able to learn a bit on the way :-)
Basically what you're asking about is called a protocol: how data is exchanged and interpreted. Traditionally you'd define your own (and odds are they'd tend to start out rather naive -- sending plain text data with newlines to indicate the end of a command, or something like that). After a while you begin to realize that more is needed (how do you handle binary data? how do you handle errors? etc, etc)
Fortunately there are libraries out there to make life easier for you. These days I tend to favor simple RPC-like libraries for most of my needs. Examples include protocol buffers (by Google), Apache Thrift (by Facebook) and Apache Avro.
I have a remote server which handles various different commands, one of which is an event fetching method.
The event fetch returns right away if there is 1 or more events listed in the queue ready for processing. If the event queue is empty, this method does not return until a timeout of a few seconds. This way I don't run into any HTTP/socket timeouts. The moment an event becomes available, the method returns right away. This way the client only ever makes connections to the server, and the server does not have to make any connections to the client.
This event mechanism works nicely. I'm using the boost library to handle queues, event notifications, etc.
Here's the problem. While the server is holding back on returning from the event fetch method, during that time, I can't issue any other commands.
In the source code, XmlRpcDispatch.cpp, I'm seeing in the "work" method, a simple loop that uses a blocking call to "select".
Seems like while the handling of a method is busy, no other requests are processed.
Question: am I not seeing something and can XmlRpcpp (xmlrpc++) handle multiple requests asynchronously? Does anyone know of a better xmlrpc library for C++? I don't suppose the Boost library has a component that lets me issue remote commands?
I actually don't care about the XML or over-HTTP feature. I simply need to issue (asynchronous) commands over TCP in any shape or form?
I look forward to any input anyone might offer.
I had some problems with XMLRPC also, and investigated many solutions like GSoap and XMLRPC++, but in the end I gave up and wrote the whole HTTP+XMLRPC from scratch using Boost.ASIO and TinyXML++ (later I swaped TinyXML to expat). It wasn't really that much work; I did it myself in about a week, starting from scratch and ending up with many RPC calls fully implemented.
Boost.ASIO gave great results. It is, as its name says, totally async, and with excellent performance with little overhead, which to me was very important because it was running in an embedded environment (MIPS).
Later, and this might be your case, I changed XML to Google's Protocol-buffers, and was even happier. Its API, as well as its message containers, are all type safe (i.e. you send an int and a float, and it never gets converted to string and back, as is the case with XML), and once you get the hang of it, which doesn't take very long, its very productive solution.
My recomendation: if you can ditch XML, go with Boost.ASIO + ProtobufIf you need XML: Boost.ASIO + Expat
Doing this stuff from scratch is really worth it.
i want to develop a pretty basic client-server program.
one software reads xml (or any data) and send it to the server who in turn will manipulate it a little bit and eventually will write it to the disk.
the thing is that if i have many xml files on disk (on my client side), i want to open multiple connection to the server , and not doint one by one.
my first question is : let's say i have one thread who keeps all the files handles and waitformultipleobjects on them, so it will know when one of them is ready to be read from disk. and for every file i have an appropriate socket who suppose to send that specifi file to the server. for the socket i can use the select function to know which sockets are ready for sent. but is there way to know that both the file and the appropraite socket are ready to be sent ?
second, is there a more efficient way to design the client, cuase on my current design i'm using just one thread which on multi processor computer is rather not efficient enough.
(though i'm sure is till better then laucning new thread for every socket connection)
third, for the server i read about the reactor pattern. it seems appropriate but still ,like my second question, seems not effient enought while using one thread.
maybe i can use something with completion ports ? think they are pretty efficient but never really used them, so don't know exactly how.
any answers and general suggestion would be great.
Take a look at boost::asio it uses a proactor pattern (see the docs) that basically uses the OS wait operations (waitforsingle/multiple,select,epoll, etc...) to make very efficient use of a single thread in a system like you're looking at implementing.
asio can read/write files as well as sockets. You could sumbit an async read for the file using asio, it would call your callback on completion then you would submit that read buffer as an async write to the socket. Asio would take care of delivering all async writes buffers as the socket completed each pending write operation.
Each of these operations is done asynchronously so the thread is only really busy to initiate reads or writes, sitting idle the rest of the time.