Click here to Skip to main content
14,242,055 members

Instant Messaging / Chat using Remoting, for LAN

Rate this:
4.87 (29 votes)
Please Sign up or sign in to vote.
4.87 (29 votes)
13 Jul 2006CPOL
Instant messaging / chat using Remoting, for LAN.

Sample Image - ChatMasala.gif

Introduction

Communication between two applications running on different (or same) systems in a Local Area Network is not a luxury, but a necessity. The .NET framework provides various solutions for solving this - Remoting, Socket Programming (TCP/UDP), Web Services etc. I will be using Remoting in my application because I believe it is the most powerful tool.

I have developed an Instant Messaging system. The system consists of a server application, a client application, and a library which is used by both the server and the client.

Without further ado, let me start explaining the code.

Using the code

Class library

The class library consists of the interface IServer and some other classes. The interface IServer dictates the functionality of the server. This information is used by the client to call the methods of the remote object.

public interface IServer
{
    bool SignUp(string username,string password);
    bool ChangePassword(string username,string curPassword,string newPassword);
    bool SignIn(string username,string password,bool visible);
    bool SignOut(string username);        
    
    bool IsVisible(string username);
    bool AddContact(string username,string contact);
    bool RemoveContact(string username,string contact);
    ArrayList GetContacts(string username);
    
    bool Send(string from,string to,string message);
    LetterReceive Receive(string to);
    ArrayList ReceiveOffline(string to);
}

LetterReceive is a class containing two string variables, from and message, and a few properties. It is very straightforward, hence I choose not to give its code.

Server

I will first explain the server class code, and once we are finished with it, I will explain the Remoting part. We will first take a look at the class hierarchy.

At the top of the pyramid, is the class Server. The Server uses the class Letter to store messages. The Server uses an object of class Database to store information which needs to persist between machine shutdowns. This includes account information and offline messages. The class Database uses the class AccountField to store information like password and contacts for a particular user. The class Database uses the class Letter to store offline messages.

We will start with the class AccountField, at the bottom of the hierarchy. Here is the code for it:

[Serializable]
class AccountField
{
    internal string password;
    internal bool isLoggedIn;
    internal bool visible;
    internal ArrayList contacts;
    
    public AccountField(string password,bool isLoggedIn)
    {
        this.password=password;
        this.isLoggedIn=isLoggedIn;
        contacts=new ArrayList();
    }
}

The class Letter has three string variables, from, to, message.

The class Database is quite simple. I will show here part of its code. The rest would be easy to guess. The Hashtable and database are used to store account information as can be seen in the method Add. It also has methods, Load and Save to load and save its instance to disk. The technique used is serialization.

[Serializable]
class Database
{
    //Fields        
    private Hashtable database;
    internal ArrayList offlineMessages;
    
    //Constructor
    public Database()
    {
        database = new Hashtable();
        offlineMessages=new ArrayList();
        Load();
    }
    
    //Methods
    internal bool Add(string username,string password)
    {
        if(database.Contains(username))
            return false;
        database.Add(username,new AccountField(password,false));
        return Save();
    }
    .
    .
    .
}

Let us come to the class Server. As can be seen, Server has inherited from the interfaces IServer and MarshalByRefObject (to enable Remoting). Once again, I will be show only the more important parts of the class declaration.

public class Server : MarshalByRefObject, ChatMasalaLib.IServer
{
    Database database = new Database();
    ArrayList letters = new ArrayList();
    
    //Constructor
    public Server()
    {
        database.Load();
    }
    public bool Send(string from,string to,string message)
    {
        if(database.ContactExists(to)==false)
            return false;

        if(database.IsLoggedIn(to))
            letters.Add(new Letter(from,to,message));
        else
        {
            database.offlineMessages.Add(new Letter(from,to,message));
            if(database.offlineMessages.Count>maxOfflineMessages)
            {
                database.offlineMessages.RemoveAt(0);
            }
            Console.WriteLine(database.Save());
        }
        return true;
    }
    public LetterReceive Receive(string to)
    {
        int length = letters.Count;
        for(int i =0;i < length;i++)
        {
            if(((Letter)letters[i]).To==to)
            {
                LetterReceive lr = new LetterReceive(
                    ((Letter)letters[i]).Message,((Letter)letters[i]).From);
                letters.RemoveAt(i);
                return lr;
            }
        }
        return new LetterReceive("","");
    }    
    public bool SignUp(string username,string password)
    {
        return database.Add(username,password);
    }
    .
    .
    .
}

Now, we come to the Remoting part. This actually enables the communication between the server and the client.

HttpChannel channel = new HttpChannel(8080);
ChannelServices.RegisterChannel(channel);
RemotingConfiguration.RegisterWellKnownServiceType(Type.GetType("Temporary_Server.Server"),
    "Server",WellKnownObjectMode.Singleton);

Client

Enough coding, let's get into action. Here is the client explained. I would first describe the Remoting initialization code.

HttpChannel channel = new HttpChannel();
ChannelServices.RegisterChannel(channel);

string hostIP = "127.0.0.1";
MarshalByRefObject obj = (MarshalByRefObject)RemotingServices.Connect(
    typeof(IServer),"http://"+hostIP+":8080/Server");
server=obj as IServer;
(obj as RemotingClientProxy).Timeout=5000;

The tough part is over, now we only have to call the methods of the variable server to work. Here, I have given a few examples:

server.SignIn("AmitDey","Password",true);
server.IsVisible("Boss");
server.Send("AmitDey","Boss","Work complete. Can I go home ?");
//Will receive 1 message if a message exists for user AmitDey
server.Receive("AmitDey");

The client code is huge, distributed into many forms. But, it's all so easy that I am not sharing it with you here. You can check it out in the source code files available at the top of this page.

Points of interest

If you are running the demo project, for your own ease, start the server application first and then the client application.

Here is a pretty ugly problem I faced. Consider the situation where the server is not loaded, but the client application is started. If the client application tries to access any method of the server variable, the client application simply hangs. It does not even cause an exception. In order to simulate a time out, I used this code. I would like to thank my friend Kuldip Saini for this solution.

(server as RemotingClientProxy).Timeout=5000;

I would also like to thank Bipin George Mathew and Kin Tutnik for helping me develop this application.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

AmitDey
Software Developer
India India
I am a Software Developer from Hyderabad, India

My MSDN Blog

My Windows Phone Apps

Comments and Discussions

 
Questiony u prefer http protocol???? Pin
asima gul khah29-Dec-06 21:53
memberasima gul khah29-Dec-06 21:53 
AnswerRe: y u prefer http protocol???? Pin
AmitDey30-Dec-06 2:57
memberAmitDey30-Dec-06 2:57 
Questiony u prefer http protocol???? Pin
asima gul khah29-Dec-06 21:52
memberasima gul khah29-Dec-06 21:52 
GeneralGlobal class Pin
asima gul khah11-Dec-06 20:39
memberasima gul khah11-Dec-06 20:39 
GeneralRe: Global class Pin
AmitDey12-Dec-06 0:30
memberAmitDey12-Dec-06 0:30 
Generalneed help Pin
imshimshal6-Dec-06 20:24
memberimshimshal6-Dec-06 20:24 
GeneralRe: need help Pin
AmitDey6-Dec-06 23:36
memberAmitDey6-Dec-06 23:36 
Questionhow to add video and audio Pin
remuz_cool23-Nov-06 22:01
memberremuz_cool23-Nov-06 22:01 
hi, my name is remuz my question is how to add video and audio, to your messanger, so a can use than like yahoo messanger in the LAN ?
thanx


--Remuz --
AnswerRe: how to add video and audio Pin
AmitDey24-Nov-06 2:17
memberAmitDey24-Nov-06 2:17 
GeneralRe: how to add video and audio Pin
remuz_cool24-Nov-06 16:33
memberremuz_cool24-Nov-06 16:33 
GeneralRe: how to add video and audio Pin
remuz_cool22-Jan-07 4:57
memberremuz_cool22-Jan-07 4:57 
GeneralRe: how to add video and audio Pin
AmitDey22-Jan-07 9:19
memberAmitDey22-Jan-07 9:19 
GeneralQuestion Pin
lucmoretti13-Nov-06 12:31
memberlucmoretti13-Nov-06 12:31 
GeneralRe: Question Pin
AmitDey13-Nov-06 15:31
memberAmitDey13-Nov-06 15:31 
GeneralRe: Question Pin
lucmoretti13-Nov-06 15:33
memberlucmoretti13-Nov-06 15:33 
GeneralRe: Question Pin
AmitDey13-Nov-06 16:44
memberAmitDey13-Nov-06 16:44 
GeneralRe: Question Pin
lucmoretti13-Nov-06 16:47
memberlucmoretti13-Nov-06 16:47 
GeneralPLS NEED BACKUP! Pin
lucmoretti13-Nov-06 17:13
memberlucmoretti13-Nov-06 17:13 
GeneralRe: PLS NEED BACKUP! Pin
AmitDey14-Nov-06 1:37
memberAmitDey14-Nov-06 1:37 
GeneralRe: PLS NEED BACKUP! Pin
lucmoretti14-Nov-06 4:07
memberlucmoretti14-Nov-06 4:07 
GeneralRe: PLS NEED BACKUP! Pin
AmitDey14-Nov-06 4:50
memberAmitDey14-Nov-06 4:50 
GeneralRe: PLS NEED BACKUP! Pin
lucmoretti14-Nov-06 4:54
memberlucmoretti14-Nov-06 4:54 
GeneralRe: PLS NEED BACKUP! Pin
AmitDey14-Nov-06 5:18
memberAmitDey14-Nov-06 5:18 
GeneralRe: PLS NEED BACKUP! Pin
lucmoretti14-Nov-06 5:20
memberlucmoretti14-Nov-06 5:20 
Generali want to change text box in message form to richtextbox but ... Pin
avish_b12-Nov-06 20:11
memberavish_b12-Nov-06 20:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Article
Posted 13 Jul 2006

Stats

254.3K views
18K downloads
95 bookmarked