Hi, today I would like to share with you idea of creating common communication components. I have done it many times and even prepared my presentation with many examples of such problem-solving. After some experiments, I created a few design diagrams that simultaneously implement communication in minimal and advanced ways. So, let me show you the design of common communicator you can create for your solution.
As you can may see, there is only two responsibilities for common communicator. There are creating clients and creating servers. And there needs to be able to that from provided TDataContract generic type. Now I want to show you design of typical TDataContract.
As you can see there are two main kind of responsibilities for TDataContract. The first is begun and end of the session, so the session management is in two methods, BeginSession and EndSession. The second kind of responsibility is dealing with messages with two methods, Consume and Publish. We can stop here because I want to simultaneously share a straightforward and powerful idea. Do you see what the type of message is? It is not a T. It is an array of T. When designing common communication components, please remember that using T[] is much better than using T in your contract. First, because you will be able to operate with 3 different types of messages, no message is by using null. When everything is fine, but you have no data, you can send an empty array as a T[0], and of course, you may decide on the server side that you send T[10] or T[100], or even T[1000000] in the message. The secret I have to share with you here is that using 100 times T and using one time T[100] have completely different performances in communication. Can you guess which one is faster? :). So that was the server site.
Now we can design client site as a consumer of the communication. The design itself is also obvious and looks like it is shown below.
The client/consumer start working with StartWorking method and stop working with StopWorking method. And between those two stages, Notified action is invoked. For the client/consumer dynamic, you can use the following design.
As you can see start and stop of working can be also exposed as begin and end session with particular key. And between those two stages, consumers consume messages with Notify events for client code.
As you can see the way of design is very easy. It uses a Long Pool pattern. And I want to share with you a competitive picture of the classic implementation with callbacks and this implementation with a long pool on the server site.
The most important different and benefit of using long pool is the way of re-establish of the connection. As you can see in the Long Pool pattern, it is a lot easier.
At the end of this entry as usually I have a present for you. There is a full implementation of presented patterns and solutions with more than just a library. There are also examples of use and performance tests of channels in WCF, Apache Thrift, and Protobuff serialization library. So, here is the content you can download.
On the left panel you can see implementation of common communicator component with different channels and on the right panel you can see bunch of examples for different channels. I decided to give you all the examples I created for one conference. Unfortunately, I could not come, so it is all yours. You need only build examples by yourself. If you want to change something inside, let me know because I wonder what you think about this solution. And here it is CommonCommunicatorWithExamples (2207 downloads). Enjoy!
P ;).