I'm writing a tcp server for an online turn-based game. I've already written a prototype using php sockets, but would like to move to C++. I've been looking at the popular network libraries (ASIO, ACE, POCO, LibEvent), but currently unclear which one would best suit my needs:
1) Connections are persistent (on the order of minutes), and the server must be able to handle 100+ simultaneous connections.
2) Connections must be able to maintain state information (user login info). [my php prototype currently requires each client request to contain the login info]
3) Optionally and preferably multi-threaded, but a single process. Prefer not to have 1 thread per connection, but a fixed number of threads working on all open connections.
I'm leaning towards POCO's TCPServer or Reactor frameworks, but not exactly sure if they meet my requirements. I think the Reactor is single threaded, and the TCPServer enforces 1:1 threading/connection. Am I correct?
In either case case, I'm not exactly sure how to do the most important task of associating login info to a specific connection with connections coming and going at random.
Boost.Asio should meet your requirements. The reactor queue can be serviced by multiple threads. Using asynchronous methods will enable your design of a fixed number of threads servicing all connections.
The tutorials and examples are probably the best place to start if you are unfamiliar with the library.
You might also take a look at MUSCLE, a multi-user networking library and server I wrote with this sort of application in mind. It's BSD-licensed, handles hundreds of users, and includes a server-side database mechanism for storing and sharing any information you want the clients to know about each other. The server is single-threaded by default, but I haven't found that to be a problem in practice (and it's possible to extend the server to be multithreaded if that turns out to be necessary).
Related
I need to work with a REST service (build with an JAX-RS implementation) in an heterogeneous environment, so I wondered how the abstractions of programming languages are converted to the real restful endpoints. I think most aspects are clear, but when it comes to asynchronous communications in REST I know several possibilities: keeping the connection open, returning a resource that can constantly be queried, chunked messages or the client transmits a callback resource.
My approach was to read the JAX-RS 2.0 Specification, but I think there is actually little stated about the REST implementation of asynchronous requests. Then I read the Jersey documentation and came to the conclusion that the JAX-RS implementations just keep the connection open for as long as the processing needs. So with "asynchronous" JAX-RS just refers to the blocking of methods on the server/client side and does not use any special behavior of REST. My first question: Is my analysis correct?
If this is the case, I have two new questions:
Is this really compliant to the REST paradigm in respect to the stateless constraint?
Considering the long-running processes that maybe work for days, is an open connection eventually automatically closed (e.g. by the OS or by a TCP timer)?
Thanks in advance!
REST architecture has got nothing to do with asynchronous programming paradigms IMO. Asynchronous implementation using #Suspended and AsynResponse interface in JAX-RS involves suspending the thread which initiated the request
To answer your questions
'So with "asynchronous" JAX-RS just refers to the blocking of methods on the server/client side and does not use any special behavior of REST'
-> REST has got nothing to do with async design in JAX-RS, but the way you design that Resource class and the setup the async method should involve RESTful principles.
Also, there is no 'blocking' as such - in fact its exactly the opposite. The I/O thread on server end is immediately suspended and returned to the container. The actual processing might still take a long time, but the real goal was to 'not block' and occupy threads. A Web container has limited number of threads dedicated to serving input requests. Prospective clients will get blocked if ALL the container threads are busy processing other clients. This is avoided by JAX-RS because it suspends the thread, returns it to the web container and responds on a different thread (internal server thread). All this increases the overall responsiveness of the application
'Considering the long-running processes that maybe work for days, is an open connection eventually automatically closed (e.g. by the OS or by a TCP timer)?'
--> Not sure what would happen in case this happens. But its not necessary to have your clients waiting 'forever' - you can specify timeouts using the TimeoutHandler (guess you might have already read this)
Just my two cents!
Right now I have:
a multithreaded windows service written in C++ which use common static libraries as well as dynamic DLLs;
each thread performs different tasks and produces different errors (DB errors, function invocation errors, etc.). Each thread further will act as a logger client (and will send all messages to a logger server);
a separate thread which has no body yet, but which will act as a logger server for handling all log messages from the logger clients.
I need a good advise of how I should implement following idea into a working solution. The idea is to add a server-client logging architecture to my multithreaded server with following requirements (though some parts I need to implement by myself, please consider just the basic idea of logger client and logger server):
there should be a lot of log clients (as I already mentioned, the log client is just an existed working thread), each should register an entity with a unique name or/and ID and following behavior:
if the logger server is up and is working now, this log client starts to send log messages,
otherwise (the logger server is down), the log client endlessly tries to register itself with the log server using a small timeout.
there should be a logger server, with following behavior:
log server registers all log clients with their unique name or/an ID and endlessly checks if there appears a new log client to be registered
log server handles all messages from different log clients and writes to DB, file, etc.
there should be an opportunity to establish connection to the log server from an external application (for example, MySuperThreadViewerProgram to monitor all thread activity/errors/etc). At the connection, the log server should consider an external application as a one more log client. It's the most important requirement.
Summing up, there are three architecture parts to be implemented:
Server-client logger architecture;
Message queue facility between log clients and log server. And log server periodically checks if there any available log clients to be registered;
Inter-process communication between log server and external application, where the latter acts as a new log client.
Please, note, I consider a logger server as a kind of log message router.
So, the main question is:
Is there any solution (software framework) which has all described above features (which is much preferably) or I should use different libraries for different parts?
If the answer is: "there is no such solution", can you review the choice I made:
For #1: using Pantheios logger framework;
For #2: using any kind of register-subscribe library with server-client architecture and message-queue support (update: ipc library) ;
For #3: using Boost.Interprocess - using SharedMemory.
UPDATE:
The good example of #2 is this ipc library. And may be I was a bit incorrect describing logger client - logger server relations, but what I really mean is similar to approach, fully described and implemented in ipc library: when one entity (thread) subscribes to another to receive its messages (or "publish-subscribe" model).
And I want to use a kind of this technique to implement my logging architecture. But in what way?
UPDATE2:
OS is Windows. Yeah, I know, under Linux there is a bunch of useful tools and frameworks (D-Bus, Syslog). May be some of you could provide a helpful link to cross-platform library, which can be useful? Maybe there is a logger framework over D-Bus under Windows?
Any comments are highly appreciated.
Thanks a lot!
ØMQ (ZeroMQ) might be a viable alternative to the ipc library you mentioned, as it has a lot of features along the lines of your requirements.
It fully supports the PUB/SUB model, allows you to work between threads, bteween processes and even between machines. It is a client-server architecture, a message queue and works as IPC, too.
Of course, you need a specific way of coding and decoding messages, the protocol buffers are indeed a great idea.
As far as I know the logging backend pantheios uses (i.e. the log sink: DB, file or whatever) is specified at link-time. The severity of logs going to the backend can be specified at launch-time and with some simple tweaks also during runtime.
If I got you right, then you have one process (let's forget about the external application just for a minute) with multiple worker threads running. Some of these threads should log to a common backend (e.g. DB) and some to another. Because pantheios cannot do this out-of-the-box you'll need to write a custom backend that can route the logs to the correct backend.
If memory consumption is not an issue and you don't need the fastest logging performance, then you might want to look into log4cxx, because it is highly configurable and could possibly spare you from implementing a client-server-architecture with all the synchronization-problems it brings about.
About the external application: If you can guarantee, that it's only one external client, then you could use a pipe mechanism to communicate with the service. The service process would then have a separate thread, which corresponds to your server thread, that opens a named pipe and can also be specified as a log sink so your worker threads can log to it as well as to other log sinks (DB, file etc.).
There are some syslog servers for win as well. Winsyslog for example is coming from the producers of the famous rsyslog. Once you have syslogd running on win, there are plenty of OS independent syslog clients, such as SysLog4j if you're using Java, or the Syslog handler for the std. python logging.
I am developing TCP server in C++(win32/linux) which cater multiple client.The server is for Video Streaming.Client request video to server and Server get it from Gateway connected with camera.
I am stuck up in the class Design.I found three classes by
Peer
Session and
ConnectionMgr.
So here ConnectionMgr is responsible for managing other Classes.
I wanted your feedback on this.
what info Peer and session need to have;
How Peer and session is related
what information needs to be modeled here.
how to do Session maintainer.
Managing multiple client will require Threads what information thoses may need.
Please give your feedback so that I can upgrade my design.
Looking at the problem space from scratch:
there's some state associated with each client that connects - you seem to split this between Peer and Session and I see no real value in that if they're 1:1 - can omit such trivia from the high-level design stage.
"what info Peer and session need to have": socket descriptor is the only crucial thing, assuming you have only one camera and stream to all clients at the same pace (losing data when socket send() blocks/can't complete due to full buffer), otherwise, a buffer too...
you have a ConnectionMgr, well - yes... it must listen and accept clients on the server socket, possibly launch a new thread per client or monitor the set of current client connections and dispatch events
you'll need to make some decisions about the I/O and concurrency model (e.g. select/poll/non-blocking, async, blocking, single threaded, thread-per-client, thread-pool etc)
this will obviously affect your design: you should decide which - or which choices - you need to support...
To get a feel for this problem space, I suggest you create a very simple client/server program - probably using threads if you're familiar and comfortable with multithreading, otherwise you can hack upon the GCC libc TCP client/server examples for a select() based solution (http://www.gnu.org/s/libc/manual/html_node/Server-Example.html#Server-Example) or try boost::asio or ACE or whatever. To start, just get it working so you can telnet to the server and whatever you type in any connection is echoed out on all the connections. That should give you enough insight to start asking more concrete questions.
As #nabulke and #Jan Hudec stated in their comments, Boost.Asio is very good solution for your problem. Have a look at pretty simple example "Async TCP Echo Server". It uses just 2 classes: server and session. No session_manager. Sessions are managed automatically by smart pointers, very convenient and simple approach.
Using Boost.Asio you can keep the network part simple (and almost optimal by efficiency using asynchronous processing). As a bonus, adding couple of code lines, you receive multithreaded server w/o headache (I would recommend this example: "An HTTP server using a single io_service and a thread pool calling io_service::run().", just ignore HTTP stuff. pay attention to boost::asio::io_service::strand used in connection class)
My customer did not gave me details regarding the nature of it's application. It might
be multithreaded it might be not. His server serves SOAP messages (http requests)
Is there any special trick in order to understand if the peer is single or multi threaded?
I don't want to ask the customer and I don't have access to his server/machine. I want to find it myself.
It's irrelevant. Why do you feel it matters to you?
A more useful question would be:
Can the server accept multiple
simultaneous sessions?
The answer is likely to be 'yes, of course' but it's certainly possible to implement a server that's incapable of supporting multiple sessions.
Just because a server supports multiple sessions, it doesn't mean that it's multi-threaded. And, just because it's multi-threaded doesn't mean it will have good performance. When servers need to support many hundreds or thousands of sessions, multi-threading may be a very poor choice for performance.
Are you asking this question because you want to 'overlap' SOAP messages on the same connection - in other words, have three threads send requests, and then all three wait for a response? That won't work, because (like HTTP) request and response messages are paired together on each connection. You would need to open three connections in order to have three overlapped messages.
Unfortunately, no, at least not without accessing the computer directly. Multiple connections can even be managed by a single thread, however the good news is that this is highly unlikely. Most servers use thread pooling and assign a thread to a connection upon a handshake. Is there a particular reason why you need to know? If you're presumably going to work on this server, you'll know first-hand how it works.
It doesn't matter if the server is multithreaded or not. There are good and efficient ways to implement I/O multiplexing without threads [like select(2) and suchlike], if that's what worries you.
I would like to create a connection between two applications. Should I be using Client-Server or is there another way of efficiently communicating between one another? Is there any premade C++ networking client server libraries which are easy to use/reuse and implement?
Application #1 <---> (Client) <---> (Server) <---> Application #2
Thanks!
Client / server is a generic architecture pattern (much like factory, delegation, inheritance, bridge are design patterns). What you probably want is a library to eliminate the tedium of packing and unpacking your data in a format that can be sent over the wire. I strongly recommend you take a look at the protocol buffers library, which is used extensively at Google and released as open source. It will automatically encode / decode data, and it makes it possible for programs written in different languages to send and receive messages of the same type with all the dirty work done for you automatically. Protobuf only deals with encoding, not actually sending and receiving. For that, you can use primitive sockets (strongly recommend against that) or the Boost.Asio asynchronous I/O library.
I should add that you seem to be confused about the meaning of client and server, since in your diagram you have the application talking to a client which talks to a server which talks to another application. This is wrong. Your application is the client (or the server). Client / server is simply a role that your application takes on during the communication. An application is considered to be a client when it initiates a connection or a request, while an application is considered to be a server when it waits for and processes incoming requests. Client / server are simply terms to describe application behavior.
If you know the applications will be running on the same machine, you can use sockets, message queues, pipes, or shared memory. Which option you choose depends on a lot of factors.
There is a ton of example code for any of these strategies as well as libraries that will abstract away a lot of the details.
If they are running on different machines, you will want to communicate through sockets.
There's a tutorial here, with decent code samples.