|
|
![]() ![]() |
Develop high quality software applications with batching, asynchrony and parallel computation using SocketPro framework Contents
A. Introduction With acceptance of TCP/IP as a standard platform-independent network protocol, almost all world class applications, such as Oracle database, MS SQL Server, MS Internet explorer, Apache, MS IIS, and so on, are heavily relied on the most successful protocol for exchanging data between two computers using LAN (local area network) and WAN (wide area network) networks. Socket API (application program interface) has emerged as the standard for network programming. On the other hand, software giants, Microsoft, IBM and Sun, have also introduced us a set of frameworks like DCOM, CORBA, Java RMI, Web service (SOAP/XML), and dotNet Remoting for simple development with object oriented design style. In most cases, these frameworks work greatly for supporting a small number of clients with fast LAN within one network domain, but they are not perfect in some cases. Here are some sample points:
B. Preface, goals and preparation We have created a framework, SocketPro, directly from socket on window platforms. Contrarily to the above frameworks, this framework meets the following goals:
This article is written to highlight SocketPro features. To experiment the SocketPro, you need to download and install the package first. After following recommended steps to start sample SocketPro servers, you start the provided client sample applications for connecting to these servers. All of samples are provided with source code. In addition to samples for old VB, you can find a lot of C++, C# and VB.NET samples inside the package. This article will illustrate data communication between a client and server first. Then, it will highlight each of key features of SocketPro. C. Data communication between a client and a server within SocketPro SocketPro has two core modules, usocket.dll and usktpror.dll. The first one runs at a client side, and the other at server side. All of SocketPro features are implemented within the two modules. All of other UDAParts modules and customer code will run on the top of the two libraries. The data communication between a client and a server can be illustrated with the following Figure 1.
Figure 1. Graphic representation of data movement between a client and a server Initially at a client side, you schedule sending any number of requests to a remote server. Inside the library usocket.dll, SocketPro will manually batches all of requests if you put these requests between the methods StartBatching and CommitBatching as shown in the attached samples. Otherwise, SocketPro will take advantage of Nagle algorithm to coalesce all of requests eventually. After manually batching requests into one single stream, SocketPro will compress the stream so that data size will be reduced to save network bandwidth if the property ZipIsOn is set to true. Right before requests are sent out, SocketPro will encrypt all of requests using either SSL or Blowfish if you set the property EncryptionMethod to one of encryption methods. At a server side, SocketPro automatically picks up the stream from a remote client. SocketPro will automatically decrypt it if it is initially encrypted. Afterwards, SocketPro will automatically unzip it if it is originally zipped. Finally, if the stream is manually batched at client side, SocketPro will automatically de-batch the whole stream into separate requests. At last, each of requests will automatically cause a proper callback function within a thread called one by one. Inside your callback functions, you can process your requests. When a request is processed, very similarly you can manually batch its result by putting its result between the methods StartBatching and CommitBatching at server side as shown in the server side samples ufilesvr.dll and uodbsvr.dll. Otherwise, SocketPro will take advantage of Nagle algorithm to coalesce all of returned results eventually. After manually batching requests into one single stream, SocketPro will compress the stream so that data size will be reduced to save network bandwidth if on-line zipping is enabled at server side. Right before results are sent out, SocketPro will encrypt all of results using either SSL or Blowfish if you require a secure data transaction. At client side, SocketPro automatically picks up the stream from a remote server. SocketPro will automatically decrypt it if it is initially encrypted. Afterwards, SocketPro will automatically unzip it if it is originally zipped at server side. Finally, if the stream is manually batched at server side, SocketPro will automatically de-batch the whole stream into separate results. At last, each of returned results will automatically cause a proper callback function (event) called one by one. Inside your callback functions, you can process your returned results. D. Batching requests at client and results at server At client side, you can manually batch all of requests into one big stream before sending them out to a remote server as shown in the following:
Similarly, at server side you can also manually batch all of returned results into one big stream before sending them out back to a client. You can find server manual batch sample code inside the ufilesvr.dll. See the code for implementation of request FindAll (idFindAll) inside the file ufileimp.cpp. Additionally you can find sample codes inside the module uodbsvr.dll if you have its source code. At client side, you can simply enable or disable the feature by setting the property ZipIsOn. At server side, it is also easy to do so by calling the function SetZip(unsigned int hSocket, bool bZip). Further, you can enable or disable on-line zipping at server side from a client by the following call:
Our test results show that online compressing could reduce data stream size 2 to 3 times typically. Therefore, this feature is helpful especially if your network has a bandwidth less than 50 Mbps. Under any cases, you should enable it at both client and server when network bandwidth is less than 10 Mbps like dial-up, DSL and cable modems as wireless and 10 Mbps LAN if your machines are not too low in speed. F. I/O completion port pump supported Beginning from version 4.8.0.1, SocketPro uses MS window I/O completion port to drive non-blocking socket events by default. It makes SocketPro support more socket connections and faster. G. Two computation modes and WaitAll At client side, by default SocketPro sends one or more requests to a remote server and returns immediately without waiting for expected results from the server. When the remote server returns one or more results, SocketPro will picks up the event and process returned results. It is SocketPro asynchrony computation. SocketPro is designed so that all of network devices (a client, routers, network cards and a server) on path are able to work concurrently at a specific time. In addition to asynchrony computation, SocketPro also supports synchrony computation for simplification of coding logical. Its performance is poor in comparison to asynchrony computation. You can very easily switch between asynchrony computation and synchrony computation at run time. Further, you can force a client socket object to wait until all of sent requests are processed and returned by calling the method WaitAll with a timeout.
For details, see the article here. SocketPro uses the above two features (batching and online zipping) plus asynchrony computation to ensure a distributed application has super performance and scalability. Because common frameworks, such as blocking socket, DCOM, dotNet remoting, web service, Corba and Java RMI, do not have these features, relatively they always run like snail in speed. For the performance comparison, see the article here. With help of SocketPro, in most cases you can even use a dial-up modem to access a remote data source and get a decent performance. Because SocketPro uses asynchrony computation by default, you will never find that client graphic user interfaces are not responsive to user events, unless you force SocketPro to run in synchrony computation and set the property Frozen to true. If you use blocking socket, DCOM, dotNet remoting, web service, Corba and Java RMI, you will mostly like to take some effort to keep graphic user interfaces from being frozen. If your network is slow one, you have to solve this problem. With help of SocketPro, you will never have such a problem at all. I. Parallel computation and no multithread at client Because SocketPro uses asynchrony computation by default, you can use one thread to host multiple socket connections in parallel. All of them can run independently and concurrently. This is also an important feature. If your project belongs to client/server application, you will never need to create a thread at client side for the sake of socket communication. Otherwise, you will most likely have to create threads and fight thread side effects, synchronization, deadlock, terminating a thread, and coding logical messing etc. J. 100% thread safe and much less thread-related problems The two core modules, usocket.dll and usktpror.dll, are fully thread safe. Additionally, provided software components, ufile.dll, udb.dll, ufilesvr.dll and uodbsvr.dll, are also thread safe. With help of SocketPro, you can easily create a thread safe library and should not often meet dead lock problems. At client side, typically you don't have to create any thread for network communication. At server side, SocketPro automatically creates a worker thread for you if necessary. Also, SocketPro automatically queues requests. Usually, you may just need to synchronize some global and static variables only if these variables will be accessed from different worker threads. K. Simplicity SocketPro is implemented with so many features, mainly because SocketPro is designed with batching, asynchrony and parallel computations directly from socket APIs. Many of them are unique and can not be found within other common frameworks such as DCOM, CORBA, Java RMI, Web service (SOAP/XML), and dotNet Remoting. Almost all of common tasks are completed to reduce your work. All you need to do is to take advantage of these features according to your requirements. If you directly use socket APIs, typically you will use connection-oriented socket, which is a binary stream protocol and has no boundary between two requests or results. Very often this feature makes socket programming complicated because a developer must have a way to decompose a stream into separate requests or results. Contrarily, SocketPro always puts boundary between any two requests or results internally. Therefore, you will be never required to decompose a big stream into requests or results no matter how many requests or results are batched at both client and server. This feature considerably simplifies development at both client and server. Use either asynchrony or synchrony computation at your will. No threading problems bother you with client side development because you can use asynchrony computation to replace worker threads under almost of cases. On server side, you will meet much less thread-related problems because of SocketPro thread pool design. Now, SocketPro comes with a tool (uidparser.exe) to create codes for both client and server using a simple universal interface definition file. You can focus coding on your business requirements. SocketPro takes care of a lot of internet communication pitfalls for you. All you need to do is to complete your business logics. There is no known pitfall with SocketPro, and your development can not be simpler! L. Multiple services on one port As shown in the provided samples, a SocketPro server is able to support multiple services, and each of them represents a set of methods for processing requests belonging to a logical task. A client can easily switch from one service to another. Here is a code snippet to show how to switch among services.
The above code snippet asks for window file service first, then find all of files in the directory of c:\windows\, afterwards switches to database service with MS OLEDB technology, and finally executes an update statement after opening a data source, a session and a command. Although there are seven requests sent to a remote server in one batch with one socket connection, they are involved with two services, file and database. At client side, there are ten events associated with a client socket object. All of common socket events are reported properly. In addition, SSL handshake events are supported. Besides, a client socket object can report user window events. For details, see the declaration of the interface _IUSocketEvent. Provided samples demonstrate how to use these events. At server side, there are also a lot of events available to you. See the declaration in the file uscktpro.h. These events include socket communication events, thread message events, various request notification events, chat service events, service switch event, customer authentication event, etc. For details, see the article focused on server development with SocketPro. Socket has a built-in chat service, which enables asynchronous communication among clients reliably. You can do p2p private communication between two clients from either client or server side. Also you can publicly communicate one or more groups of clients from either client or server side. The chat message can be any data. You can use this service to fast notify clients or a server anywhere when some interesting happens at either one client or server. Alternatively, you may create your own notification services with your own business requirements O. Transparent detection of broken socket connections SocketPro is implemented directly with window socket library. It has a lot of events. One of SocketPro advantages over other common frameworks is that SocketPro is able to automatically and fast report a socket connection broken event at both client and server side. For example, shutting down a connected client application can quickly cause the event reported at a SocketPro server. Similarly, shutting down a connected server application can quickly cause the event reported at a client application. In case of abnormal socket shutting down like power off and wire unplugging, SocketPro is also able to handle the event at both client and server, although it takes much more time (usually 1 to 2 minutes) to catch it. You will never find a dead socket at server side for more than two minutes by default. SocketPro doesn't implement this feature at client side, but with help of a timer you can also simply kill a dead socket at client side by sending a base request to a server periodically. In short, SocketPro requires no code from you to detect broken socket connections. P. Secure data communication and customer authentication One of your concerns is security for accessing a remote data source through internet. At this time, SocketPro is embedded with MS SSPI and OpenSSL libraries to secure data communications using secure socket layer (SSL). Additionally, SocketPro is implemented with Blowfish to selectively secure some of requests or returned results. In many cases, we truly want to authenticate a socket connection from a remote client, and like to know who makes the connection. According to client credentials, we decide if we should open or close a door to a remote client. SocketPro makes customer authentication possible and simple. See the provided sample code of RemoteConnector. Q. Online monitoring network traffic SocketPro provides lots of methods for you to diagnose data traffic on your network. At run time you can detect (1) how many bytes are received and sent at both client and server, (2) how many requests are coming or to be processed at both client and server, and (3) what bandwidth my network has. These features are essential to responsive client graphic user interfaces. For example, you can display the number of bytes received and how many requests have not been processed using a window so that a user knows a set of data transactions are still in process at a specific time. At client side, SocketPro implements three timeouts for building socket connection, receiving results and sending requests. They are all configurable at run time easily. You can cancel requests to be processed at server side. Actually, they are two ways to do so with SocketPro. One is a hot way that you simply abort a socket connection. The other is a soft way that you send a request Cancel from a client to a server. When the server gets this particular requests, it will cancel requests queued to be processed. The first way will lost all of state data associated a socket and you will have to rebuild a socket connection. The second way will not lost state data and there is no need to re-establish a socket connection. For example, we like to abort fetching a large bulk of records from a server to a client, to cancel coping or sending a file between a client and a server, and so one. T. No NAT and firewall problems Don't ignore these problems. Sometimes, these problems are extremely painful to users and administrators for the sake of security. DCOM has these problems. MS dotNet remoting still has these problems too. SocketPro is friendly to NAT and firewall network devices. You can configure these devices so that clients can access a remote SocketPro server protected by these devices. Note that there is no need to configure any network device at client side with SocketPro. U. Very low dependency and memory footprint SocketPro is written using window system APIs only, which leads SocketPro with very low dependency. It is very simple to deploy SocketPro. SocketPro is carefully engineered with very lower memory footprint. In comparison with other remoting frameworks, it requires far low memory. V. Great integration, reusability, and modularity as well as version control Software integration and reusability are extremely important and critical to a real professional software. At client side, SocketPro uses the two methods, IUFast::SendRequestEx and IUFast::GetRtnBufferEx (or IUSocket::SendRequest and IUSocket::GetRtnBuffer), to send requests to and get expected results from a remote server, respectively. At server side, SocketPro uses the two methods, RetrieveBuffer and SendReturnData, to retrieve the coming requests from and send results back to a client. As you see, its data communication between client and server is based on an array of bytes. Therefore, any development language that can compose and decompose an array of bytes is able to communicate a remote server software component written from another development language, as shown in attached samples. Therefore, you can easily get different codes to communicate among them. Further, unlike common interface-based frameworks such as DCOM, Java RMI, Corba and dotNet remoting, the change in the signature of a client request (method) does not have to cause the server code changed. Similarly, the change in server code will not have to cause client code to be modified. By this time, you should understand that SocketPro naturally has much better integration and reusability theoretically and practically. SocketPro client and server codes are loosely coupled, and not tightly connected. In short, whenever you change the signature of a method of DCOM, Java RMI, Corba and dotNet remoting, you have to change server code and recompile/reinstall both client and server. On the other hand, you will not do so with SocketPro in many cases. In some cases, you may need to do so. It is very difficult to get Java to talk with dotNet remoting and you have to rely on a third party software component in many cases, but with help of SocketPro, it is much easier to get the two communicated (At this time, SocketPro java version is not implemented yet but it is listed on the top of our To-DO list). Modularity and version control are also important to a real software. At the present, SocketPro client uses classical and approved MS COM technology to ensure that all of development languages are supported. All of client objects are written from ATL/COM and supports both free-threaded and single threaded apartments. In regards to dotNet platform, this approach suffers a little performance loss with high speed of networks, but it has no suffering if your network bandwidth is not more than 50 Mbps. Our test shows that the performance of IURowset::GetData inside udb.dll is decreased about 20% if your network bandwidth is 100 Mbps or high because of extensive interop marshalling between native code and managed code. If your network bandwidth is not more than 10 Mbps, you should never feel any performance loss under all of cases. At server side, as shown in samples SocketPro strongly advocates C/C++ dll approach for better modularity as described in this article. SocketPro also has a mechanism to control versions of client and server software components. Whenever a client calls the function IUSocket::SwitchTo, a structure named as CSwitchInfo is sent to a remote server. By the same token, a structure CSwitchInfo comes back to the client after a successful switch at the server side. The structure contains client or server implementation version data with five customer defined parameters. Therefore, you can use the structure to control implementations at both client and server at run time. This is helpful when you have to re-code some functions but you can not simply modify the code in the other side. W. Communication among different platforms At this time, it is not implemented yet. However, SocketPro is designed with this important feature in mind. We'll complete it with supporting Java, Linux, MacOS, and major Unix systems. X. One guarantee from UDAParts UDAParts offers you the following
guarantee: |