Tuesday, August 18, 2009

Global Text Chat Room Application using C#.Net Programming - Remoting technology

The basic and simple architecture of .Net Remoting technology has three parts, these are –
1. Base Remoting class: This is like a bridge to communicate between Client and Server. It exists in a DLL file which shares Server and Client program.
2. Server class: It is server to server Client requests, every client connect to Server to communicate each other. This program holds a Remoting class’s DLL.
3. Client class: This is client part of Remoting architecture. This also holds a copy of Remoting base DLL. It connects to Server and via server communicates to other client.This is very simple idea of Remoting architecture, if you want to learn about this technology then you may read from MSDN site. I am not going to explain about its theory, I am focusing mainly about its application.

Now I will describe about a Global Text Chat Room application using this technology. This is very easy to develop and interesting also. In this program I have not covered about thread related issues, this is very basic type of chat application.



As Remoting architecture here has a base class and after compiling produces a DLL file with name ‘RemoteBase.dll’. This DLL has about six methods like, JoinToChatRoom, LeaveChatRoom, SendMsgToSvr (Send Message To Server), GetMsgFromSvr (Get Message From Server) etc.




Next one is Server, this is a Windows Form (WinForm) application. This application uses ‘RemoteBase.dll’ as its reference file for library. Server registers a TCP channel with a port number. You may choose any port number from 1025 to 65k. And it registers for well known type of RemoteBase and mode type is Singleton. (Remember it should not work for Singlecall type, details and different will found on MSDN).
When you run server you will see a window as attached screen shot and need to press button ‘Start’ to start server and check server status as ‘Running’. To stop the server need to press on ‘Stop’ button.




Last one is Client part, it also a Windows form (WinForm) application with two windows forms. As server client also take reference of ‘RemoteBase.dll’ for library. When you run this client application one popup window will come and ask for your name which will be used to chat room to represent you. Then press on Join button. After that chat room window will open.

There also has server address like ‘tcp://localhost:8080/HelloWorld’ here ‘localhost’ is server address and 8080 is port number. Server address needs to tell where your server is running. I am using server and client in same machine so server address is ‘localhost’ you may give any IP address here. Port number also can be changed but server opening port number and client requesting port number should be same. You can not change reaming thing in address otherwise this chat application will not work.


Chat room window has four sections largest one to see all chat message and below of that to type chat message, and send button to send message to server. Just above list to display all online user.

When you put your name then client application creates a remote base class’s object and connects to server by registering TCP channel. Then connects to Chat Room and seek latest message number. After that main Chat Room window opens. From that window it seeks latest available message in server by a timer. To get message from server it invokes ‘GetMsgFromSvr()’, and get available online user through ‘GetOnlineUser (), and user message sends from client application to server by invoking ‘SendMsgToSvr()’. For better understanding you may go through the code.

Source code as below and full source code can download from following link:

How the code is working

Start the Server:

When users are trying start Server by clicking Start button the following code executes –


private void btnStart_Click(object sender, EventArgs e)

{
if (channel == null)
{
channel = new TcpChannel(8080);
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(SampleObject), "ChatRoom"WellKnownObjectMode.Singleton);
lblStatus.Text = "Running...";
btnStart.Enabled = false;
btnStop.Enabled = true;
}
}
Here a TcpChannel opens with port number 8080 and register it as WellKnownServiceType. ‘ChatRoom’ it is the ‘ObjectUri’ it will require to connect to server from client.
On the other hand when user press to ‘Stop’ server then unregister the channel and stop the server. Codes are below-
private void btnStop_Click(object sender, EventArgs e)
{
if (channel != null)
{
ChannelServices.UnregisterChannel(channel);
channel = null;
lblStatus.Text = "Stopped.";
btnStart.Enabled = true;
btnStop.Enabled = false;
}

}


Join to ChatRoom:
Next coming the client, how client connect to server and user login to the chat room. To joining to chat room the below codes are executes
private void JoinToChatRoom()
{
if (chan == null && txtName.Text.Trim().Length != 0)
{
chan = new TcpChannel();
ChannelServices.RegisterChannel(chan,false);
// Create an instance of the remote object
objChatWin = new frmChatWin();
objChatWin.remoteObj = (SampleObject)Activator.GetObject(typeof(RemoteBase.SampleObject), txtServerAdd.Text);
if (!objChatWin.remoteObj.JoinToChatRoom(txtName.Text))
{
MessageBox.Show(txtName.Text+ " already joined, please try with different name");
ChannelServices.UnregisterChannel(chan);
chan = null;
objChatWin.Dispose();
return;
}
objChatWin.key = objChatWin.remoteObj.CurrentKeyNo();
objChatWin.yourName= txtName.Text;
this.Hide();
objChatWin.Show();
}
}
Here from user client application takes a name and check to server is the name available or not. If name is available then user gets the ‘CurrentKeyNo’ of server, it is the number of last chat message (how the key generated, describe in later) and open the ChatRoom window.
If user name is already taken by other user, then application asks to user for different name.
In server side to join a user in chat server “JoinToChatRoom()” method invokes, lets see what happens within the method –

public bool JoinToChatRoom(string name)
{
if (alOnlineUser.IndexOf(name) > -1)
return false;
else
{
alOnlineUser.Add(name);
SendMsgToSvr(name + " has joined into chat room.");
return true;
}
}
Here is user can successfully logged in to server then his name is added in a user collection, ‘alOnlineUser’ is it an ArrayList type object.


Send message to server:
When user type some message and press on ‘Send’ button or just press ‘Enter’ button then client application try to send message to server. To do it client call the below method –
private void SendMessage()
{
if (remoteObj != null && txtChatHere.Text.Trim().Length>0)
{
remoteObj.SendMsgToSvr(yourName + " says: " + txtChatHere.Text);
txtChatHere.Text = "";
}
}
Here client application in invokes the “SendMsgToSvr()” method of server. Let’s see the method what doing-
public void SendMsgToSvr(string chatMsgFromUsr)
{
hTChatMsg.Add(++key, chatMsgFromUsr);
}
Wow! This is very small code. Actually this is adding the users’ message to another collection. I have used for this collection of HashTable type, you may use any other collection type to store string data.
See here has one counter ‘key’ which is incrementing by one. This is the counter which is maintaining the chat message number. It will help us to get chat message from server.
Receive Message from Server:
Ok friend, next look at how data are getting from server –
In chat room a timer always fires, which try to get message from server and current available user in server. Here below codes plays in Client side –
private void timer1_Tick(object sender, EventArgs e)
{
if (remoteObj != null)
{
string tempStr = remoteObj.GetMsgFromSvr(key);
if (tempStr.Trim().Length > 0)
{
key++;
txtAllChat.Text = txtAllChat.Text + "\n" + tempStr;
}
ArrayList onlineUser = remoteObj.GetOnlineUser();
lstOnlineUser.DataSource = onlineUser;
skipCounter = 0;
if (onlineUser.Count < 2)
{
txtChatHere.Text = "Please wait untill atleast two user join in Chat Room.";
txtChatHere.Enabled = false;
}
else if(txtChatHere.Text == "Please wait untill atleast two user join in Chat Room." && txtChatHere.Enabled == false)
{
txtChatHere.Text = "";
txtChatHere.Enabled = true;
}
}
}
Here client invokes “GetMsgFromSvr()” method to get message, with parameter key. The codes of the method are –
public string GetMsgFromSvr(int lastKey)
{
if (key > lastKey)
return hTChatMsg[lastKey + 1].ToString();
else
return "";
}
The server just takes the key as last-key of user’s message and uses it in Chat message collection to fetch the next chat message, after that the message return to the client.
To online user client application invokes “GetOnlineUser()” method, lets see what happen in server side within the method.
public ArrayList GetOnlineUser()
{
return alOnlineUser;
}
So this method returns the user collection object which was created in “JoinToChatRoom()” method.

Leave the Chat Room:
When user closes the chat room, then client application request to server to remove his/her name from server’s online user list. In client side the below method invokes –
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (remoteObj != null)
{
remoteObj.LeaveChatRoom(yourName);
txtChatHere.Text = "";
}
Application.Exit();
}
In server side the “LeaveChatRoom()”method invokes, the code of that method is –
public void LeaveChatRoom(string name)
{
alOnlineUser.Remove(name);
SendMsgToSvr(name + " has left the chat room.");
}
Now server has deleted your name from online user list.

10 comments:

sanjay said...

it helps me alot for understanding the socket programming and to do my project....

Ki seok said...

I am not allowed to get http://rapidshare.com/files/276755910/GChat_RemoteBase.zip.

Could you check that link please.

I appreciate with it in advance.

Your code helps me a lot :)

Dave said...

Hello!

This is some great code you wrote!

Is it possible to send a private message chat to any person displayed in listbox?

I've been trying but have had no success. :(

Any help you could provide would be very appreciated !!

Thank you!!

Suman Biswas said...

Hi,
You can change this code to individual chat. To change this you need to modify the code. Just do these things-
1. Set every user by unique id and save this in server.
2. Populate a array (multi dimensional or string message with CSV) with from user id, to user id and message.
3. Try to fetch data from Server for a specific interval providing with user id.
4. Server will check for every user request with their id in the populated array. If any message available for this user then server will send message to user.

If you follow these steps then you can develop this type of chat system.


Thanks,
Suman

Salmon Riaz said...

is it easy to replicate this in ASP.Net and is architecture very similar>

kunal said...

HI My self Kunal .... the given source code not working ... can u please give me a new link.......

Andreea said...
This comment has been removed by the author.
Andreea said...

Hi!I want to run the application on two computers. What should I do?
Thanks!

Nousheen Hashmi said...

Please help me out in making this code to be converted to private chat room.please can you provide me the required chunk of Code.i have been trying a lot to implement your algo steps but m not successful in doing this.M doing my final year project in developing Inter-office Communication System in .net.here i require the members to private chat with each other.i will be waiting for your reply...Reply SOOn.............Plz...Thanks in advance

محمدقايد البحري said...

اريد