In my opinion you should write a server and both the event consumers and event producers should be clients. Basically your library would be just a client that sends/receives messages from the server. This has many-many benefits:
- Your processes can be on different machines.
- Socket communication can be programmed in almost all langauges.
- One of the most crossplatform languages is C/C++ and in this language you have a more or less standardized socket api.
Don't forget to use a data exchange format that is easy to handle in most languages/scripts. If you don't want to save with bits then I recommend xml or json.
There are many-many frameworks and libraries that you can use to get the job done easier in different languages. I myself usually prototype/test such simple client/server architectures in python where putting together a simple socket server/client takes only 1-2 pages of code and then I can write conforming clients/servers in different languages easier by being able to test it with the python client or server that can be written easily/quickly if you know python.
Note: There are (persistent/non-persistent) message queue solutions and subscription systems that basically implement what you need. Passing a message and receiving it somewhere else... But if you are writing this to learn something then let's reinvent the wheel just for fun! :-) You can learn a lot from this!
EDIT: Persistent and non-persistent message queues: These are quite high level concepts just like a "message bus". You can search for actual implementations with google, I don't link one as creating an implementation in a language is not easy (creating a roboust ones can be more challenging) - I would rather just explain it. A message queue is just a message queue somewhere. It maybe be stored in memory, in pure files, or in a database, or anywhere else. It must be accessible by the "consumers" and "producers" of the queue by using some library. In some scenarios these consuer/producer programs don't even have to know about the actual implementation (whether the queue is in memory, in db, or somewhere else in networking engine buffers between apps) because this is just an implementation detail. If you implement a message queue over tcp protocol then you have an implementation but if you defined a nice general interface then you can easily replace the implementation without modifying the client that uses the interface. I don't have much to tell you about simple pure message queues. Persistent message queues: These are usually implemented in the form of a message queue server backed with a db. You connect with a producer client and you just pass in messages to the queue. You can also connect with consumer clients and you can pull out the messages. The queue is persistent because messages are always persisted and never get lost. If you send a message by a producer client when there is no consumer client connect then the persistent message queue server just stores the message and when the consumer connects it can pull the messages even if they were put to the queue one week before and currently the producer client is disconnected. If you stop the message queue server then its messages are persisted to a db.
"Message bus": This is also a high level concept and I wouldn't compare it with a an actual building block for an implementation like "sockets". TCP socket is just a building block, a possible way to build up a communication channel between two machines or between different(same) processes on a single machines (yes, sockets can also be used as pipes, I love it for this flexibility!). You can actually implement a message bus with TCP connections but its probably not the most effective solution.
Here we can separate your problem into many layers:
1. The first layer is the high level description of your actual problem and the list of requirements that your solution must meet. For example being able to effective do this and that while the other 2-3 operations can be less effective as a tradeoff. The list of requirements will help you to decide which of the possible implementations to choose. Usually there is no "best" "general" solution. If you don't know what you want to do, if you are just playing around then don't try to find a "best"/"optimal" general solution because usually there is no such solution.
2. If you know the problem and you have the requirements then try to find out what kind of operations do you have to perform to do the job effectively. In case of operations I'm thinking about something like a sequence-diagram in case of uml. For example: In case of creating a new user I have to send a create-user message and as a response I get OK/Failure. But these "operations"/"function calls" can be more complicated than this simple example. In this layer we can think about the problem as either "packet/message" exchange or function calls but I like thinking in "function calls" more, this is why: In case of network communication you are usually performing function calls. You serialize the function call parameters, you send them over the wire, and later you get back the serialized return value of the function call. In case of an optimal solution this function call is asynchronous (like the Begin*** calls in C#), you are just starting the function call and as an extra parameter you specify a callback to be called when the result of the operation came back (from somewhere, from a subsystem, from a service, from the network, ...).
1. Choosing actual implementations to realize the building blocks of your solution. For exmaple as a communication channel of your "function calls" you can provide a TCP or UDP based channel or a PIPE, an SSH connection maybe something else... If you separate the channel implementation with an interface then you can play around with this later. In some cases however you need some really optimized communication (like in case of Quake3) but in my opinion such optimization is needed only in 0.00001% of networking apps... Q3 needs very low latency while most apps don't - elegant solutions have almost always priority over optimized ugly ones.
As a first step try to think about the 1st and 2nd layer I was talking about. As a first implementation I would recommend you a simple server/client approach with TCP. A centralized server (as any other solutions) have many benefits and disadvantages.
Some benefits:
- If you put a server to public on the internet you can easily connect with a service from anywhere, even from internal networks from behind NAT.
- It is very easy to program a centralized logic that is inside one server.
Disadvantages:
- You actually need a server somewhere in contras to peer to peer.
- Single point of failure if you server architecture is overly simple.
Any solution has its benefits and disadvantages. There is no perfect. If you know what you want to do and what you need then you can decide which advantages brings you the most benefits with acceptable drawbacks.
If you are just playing around then write a simple TCP server first where clients connect and ask the server to perform something. For example the server may provide the following operations (function calls):
- Add event
- Get all events
If you want several applications then I don't see why couldn't you do that with a TCP server: You send an app id in all function calls, this way you can direct the request/function call to an app specific part of the server. If you want the server to be extendable you can also do that, a client could register as an app and all events that are sent to the server with the app's id could be directed to the app, then the result from the app back tot the server and finally from the server back to the client. I know, this isn't the most optimal solution but believe me, if you implement one like this you will find so many problems in the way, you will learn a lot if you implement this once, then again more elegantly, and then again (for example by using a serialization framework, by abstracting away communication channels, by using async (network) IO...
Don't hesitate especially if you are doing this "just because". Start the TCP server implementation, it will be a challenge for sure.
Updated 17-Mar-14 12:56pm
v3