The whole architecture of WinChat For .NET is very simple. All it involves is 3 classes:
- TcpUdpServer -- handles all the server functionalities like listening to
connections and receiving messages;
- TcpUdpClient -- handles all the client functionalities including call request
and call initiation;
- WinChatFormLibrary -- handles all the Windows Form Controls, and also acts as a middle agent for the communication between TcpUdpClient and TcpUdpServer.
This project makes heavy use of the Multi-Threading, Delegate and Socket programming techniques in communication. It also depends on some protocol-like handshakes to setup the chatting sessions. Fig. 1 depicts the procedures a call is set-up.
Fig. 1: Call Setup Procedures
When either side of the party wants to initiate a call request, the following procedures will take place before both parties can start the chat session.
- The calling side gives the remote side's (called side's) hostname to the
WinChatFormLibrary and press the "Notify" button;
- The calling side's TcpUdpClient sends the "Notify Request" to the
called side's TcpUdpServer;
- The called side's TcpUdpServer returns the "Notify Accept" message
back to the calling side;
- The calling side's TcpUdpClient sets up a TCP connection to the called side's
TcpUdpServer;
- The calling side's TcpUdpClient notifies its own TcpUdpServer that it is
already involved in a chat session (through raising an event), so that the TcpUdpServer
will reject all the additional call requests until this on-going call ends;
- The called side's TcpUdpServer notifies its own WinChatFormLibrary that a
call has been setup from the calling side (through raising an event);
- A delegate function in the called side's WinChatFormLibrary is invoked by
the call initiation event;
- The called side's TcpUdpClient, invoked by the delegate function in its own WinChatFormLibrary, will setup a TCP connection to the calling side's TcpUdpServer based on the hostname obtained from the TcpUdpServer.
It is noteworthy that two TCP connections are created for a call, one for each direction. I could have done it with only one connection for a call, but I chose this way. The reason is that the architecture of the program contains one client and one server that are quite independent to each other, I feel that it's more logical to have both sides (the calling and the called sides) do similar things to each other (kind of like a mirror to each other). Thus, I decided to have each side create one TCP connection to the other. Fig. 2 depicts the procedures a call is terminated.
Fig. 2: Call Termination procedures
When either side wants to terminate the call, the following procedures will take place (Note: either the calling side or the called side can terminate the call at any time):
- When the terminating side wants to terminate an on-going call, he/she will
press the "Hangup" button in the WinChatFormLibrary;
- The terminating side's TcpUdpClient will send a "Notify Hang-up Request"
message to the terminated side's TcpUdpServer;
- The terminated side's TcpUdpServer will reply with a "Notify Hang-up
Accept" message to the terminating side's TcpUdpClient;
- The terminating side's TcpUdpClient will send a TCP message "Notify
Last Message" to the terminated side's TcpUdpServer, so that the terminated
side's TcpUdpServer will close the TCP socket for this connection;
- The terminating side's TcpUdpClient will now close the TcpClient's socket;
- The terminating side will notify its own TcpUdpServer (through raising an
event) that the on-going call has ended, so that the TcpUdpServer can accept
incoming call requests;
- The terminated side's TcpUdpServer will notify the WinChatFormLibrary that
the terminating side has already ended the on-going call (through raising an
event);
- A delegate function in the WinChatFormLibrary will be invoked by the call
termination event;
- The terminated side's TcpUdpClient, invoked by the delegate function in
its own WinChatFormLibrary, will send the TCP message "Notify Last Message"
to the terminating side's TcpUdpServer, so that the terminating side's TcpUdpServer
will close the TCP socket for this connection;
- The terminated side's TcpUdpClient will now close the TcpClient's socket;
Thus, the call setup and termination can easily be handled by a few very simple steps based on the Socket and Delegate facilities provided by the .NET architecture. It's noteworthy that, although the above steps are described in procedural form, some of the steps actually happen simultaneously.
Comments