Click here to Skip to main content
15,868,292 members
Articles / Programming Languages / C#
Article

Making Peer-to-Peer Chatting Easy

Rate me:
Please Sign up or sign in to vote.
4.00/5 (8 votes)
16 Apr 20064 min read 96.5K   5.7K   47   16
Using Microsoft's Peer-to-Peer technology and Adrian Moore's encapsulation, to create an easy to use library for chatting.

Introduction

Microsoft has created a set of technologies for creating peer-to-peer applications. These technologies represent low level building blocks that can be used to build many types of applications. Adrian Moore has explained these technologies in several CodeProject Articles. He has also brought these technologies to the managed programming world.

For our senior project at Michigan State University, we were asked by Microsoft to create a set of classes that can be used to quickly create peer-to-peer applications. Since there had already been work done by Adrian to do this, we decided to create an extension of his library that would focus on creating chatting style applications easily. This article shows how we created it.

Thinking About Chatting

To begin our library, we looked at several types of chatting applications. It seemed that everywhere we looked, there was chatting going on. Whether it's through your favorite instant messaging client, or in a channel on IRC, or even on a blog website that several authors contribute to, all of these types of interactions could be thought of as chatting, just with a slight skew on naming and presenting.

What we concluded was that all of these styles of chat applications could be considered a "chatroom", and different people exchange "messages" there that persisted for varying lengths of time.

Using Graphs and Records

When we looked at the peer technologies offered by Microsoft and Adrian, we were especially drawn to the graphing technology. Graphs can be thought of as a database of records, which is similar to how you can consider lots of chatting applications: as a chatroom of messages.

So we created a class that modeled this basic relationship, and called it Chatroom. In our model, the Chatroom handles all of the networking code needed to set up a graph and connect to peers in the same chatroom. Below is a simplified version of the Connect() method.

C#
//start a graph for local use
_graph = new Peer.Graph.PeerGraph(this.Name);

//generate a unique identity to connect to the graph
_chatID = Guid.NewGuid();
ChatID = _chatID.ToString();

//create a local database in case it doesn't exist
Peer.Graph.PeerGraph.Create(this.Name, ChatID, DatabaseName);

//open the database once it's created
_graph.Open(DatabaseName, ChatID );

As you can see, we first create a graph (which will fail if someone has already created one) and then open it for connections to other peers. The Chatroom also handles converting messages into records. Below is a simplified version of the Send(Message) method:

C#
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream memory = new MemoryStream();
Peer.Graph.PeerRecord record;
            
formatter.Serialize(memory, message);

record = _graph.CreatePeerRecord(CHAT_MESSAGE_RECORD_TYPE, 
         message.Lifetime);
record.DataAsStream = memory;

_graph.AddRecord(record);

As you can see, we actually serialize the entire object as the data of a record. Using this method makes the data reliable as it cannot be deserialized unless the entire messages is received. We used this method for transmitting all of the data that needs to be synchronized in a chatroom.

Events

Like most Windows APIs, the peer-to-peer technology publishes events that your program can listen to. We are able to publish events specifically for Users and Messages in our library, by subscribing to peer events. When a record gets added to the database, we determine what type of record it is and fire the correct event. Below is a simplified version of how we determine which event to fire based on a graphing event.

C#
Peer.Graph.PeerRecord record;
BinaryFormatter formatter = new BinaryFormatter();
            
switch (e.Action)
{
    case Peer.Graph.PeerRecordAction.Added:

    if (e.RecordType == USER_RECORD_TYPE)
    {
        //get the record from the database
        record = this._graph.GetRecord(e.RecordId);

        //deserialize the user instance embedded in the record
        PeerChat.User user = 
          (PeerChat.User)formatter.Deserialize(record.DataAsStream);

        //let anyone who wants to know, know that someone joined
        if (this.UserJoined != null)
        {
            //attach the user to the user event
            UserEventArgs args = new UserEventArgs(user);
            UserJoined(this, args);
        }
...

As you can see, we only have to retrieve the record out of the database and instantiate it as an object that we can then work with.

UI Controls

After creating the classes needed for our infrastructure, we wanted to make it easy for developers to make a Windows Forms application. To do this, we created custom controls that have a Chatroom associated with them. We used the events published by our Chatroom to control how they behave. Take this example of the UserList control which provides a visual representation of the presence in a chatroom.

C#
m_chat_room.UserJoined += new 
  PeerChat.Chatroom.UserEventHandler(m_chat_room_UserJoined);
...
void m_chat_room_UserJoined(object sender, PeerChat.UserEventArgs e)
{
    AddUserToList(e.User);
}

public void AddUserToList(PeerChat.User the_user)
{
    if (this.InvokeRequired)
    {
        UserCallback methodToCall = new UserCallback(AddUserToList);
        Invoke(methodToCall, new object[] { the_user });
    }
    else
    {
        this.Items.Add(the_user.Name);
    }
}

The InvokeRequired flag is used because updating a Windows Forms control from a different thread (the peer thread) is not a safe practice. In the example above, the name of the user who had joined the Chatroom is added to the Items of a list box.

Conclusion

While there are many other aspects of the peer-to-peer technologies, we did not cover them in our project, we hope that our venture into this world will save some time for developers using this type of technology. There are also many aspects of the PeerChat library that we have not discussed in this article, but if you would like to learn more, you can download the source code to PeerChat on the top of this page. You can also learn more about graphing by viewing Adrian Moore's CodeProject articles.

About The Project

PeerChat was developed by Mike Fazio, Dan Lash, Carly Szekely, and Tom Vollman at Michigan State University. The website for the project is located here.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
Dan Lash is a Computer Science and Engineering senior at Michigan State University. He is interested in ease of use of software for developers and for end users.

Comments and Discussions

 
GeneralHelp about peer to peer list sharing Pin
circass28-Nov-07 8:21
circass28-Nov-07 8:21 
GeneralRe: Help about peer to peer list sharing Pin
DanLash28-Nov-07 9:09
DanLash28-Nov-07 9:09 
GeneralRe: Help about peer to peer list sharing Pin
circass28-Nov-07 9:23
circass28-Nov-07 9:23 
QuestionHow can I make my apps run on windows 2000 OS with the microsoft peer-to-peer SDK? Pin
Kyou gun6-Sep-06 20:59
Kyou gun6-Sep-06 20:59 
AnswerRe: How can I make my apps run on windows 2000 OS with the microsoft peer-to-peer SDK? Pin
DanLash7-Sep-06 5:01
DanLash7-Sep-06 5:01 
QuestionHow can I make my p2p Application support audio or video streaming use the peerchat Pin
Kyou gun17-Jul-06 1:59
Kyou gun17-Jul-06 1:59 
AnswerRe: How can I make my p2p Application support audio or video streaming use the peerchat Pin
DanLash19-Jul-06 16:43
DanLash19-Jul-06 16:43 
GeneralRe: How can I make my p2p Application support audio or video streaming use the peerchat Pin
Kyou gun4-Aug-06 13:19
Kyou gun4-Aug-06 13:19 
QuestionI Can not get the Msg_history and User_list control, Why Pin
Kyou gun16-Jul-06 18:58
Kyou gun16-Jul-06 18:58 
AnswerRe: I Can not get the Msg_history and User_list control, Why Pin
DanLash19-Jul-06 16:45
DanLash19-Jul-06 16:45 
GeneralRe: I Can not get the Msg_history and User_list control, Why Pin
Kyou gun4-Aug-06 13:19
Kyou gun4-Aug-06 13:19 
Generalhi,i can't run the program Pin
larson00121-Apr-06 16:39
larson00121-Apr-06 16:39 
GeneralRe: hi,i can't run the program Pin
DanLash25-Apr-06 11:07
DanLash25-Apr-06 11:07 
GeneralRe: hi,i can't run the program Pin
circass28-Nov-07 4:45
circass28-Nov-07 4:45 
GeneralHi Pin
rajat talwar16-Apr-06 19:30
rajat talwar16-Apr-06 19:30 
GeneralRe: Hi Pin
DanLash16-Apr-06 19:34
DanLash16-Apr-06 19:34 

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.