Click here to Skip to main content
16,020,669 members
Articles / Programming Languages / C# 4.0
Tip/Trick

Simple Chat program in C#

Rate me:
Please Sign up or sign in to vote.
4.81/5 (38 votes)
17 Jun 2013CPOL2 min read 287.1K   32.3K   52   29
This is a simple chat program using WCF with NetTcp binding.

Introduction

This is a simple chat program with a server and can have many clients. The server needs to be started first and as many client can be started then. This code uses NetTcp binding to communicate between server and client.

Background

NetTcp binding is one type binding in WCF suitable for cross-machine communication. To have the client communicate with server, CallbackContract is used.

Using the Code

First, I have the interface called ISendChatService with Start, Stop and Send message. This interface will have service contract and also have a callback contract IReceiveChatService. Whenever new client starts, the client will send start("LoginName") to the server. Thereafter, the client will send message to another client by using SendMessage("Message","AnotherClientName"). When client closes the message Stop("LoginName") will be sent to server and server removes client from list. And list of available client list will be sent to all clients.

C#
[ServiceContract(CallbackContract = typeof(IReceiveChatService))]
    public interface ISendChatService
    {
        [OperationContract(IsOneWay = true)]
        void SendMessage(string msg,string receiver);
        [OperationContract(IsOneWay = true)]
        void Start(string Name);
        [OperationContract(IsOneWay = true)]
        void Stop(string Name);
    } 

The callback interface IReceiveChatService. ReceiveMessage method will be used to receive a message from server sent by a client. Whenever new client is added, server will send list names.

C#
public interface IReceiveChatService
{
    [OperationContract(IsOneWay = true)]
    void ReceiveMessage(string msg,string sender);
    [OperationContract(IsOneWay = true)]
    void SendNames(List<string> names);
}

Sample Image - maximum width is 600 pixels

Below is the ChatService class which implements ISendChatService. Here the server has a public static event so that any client that comes in the event will fire and give the list of clients. If static is not defined for the event, then for each client the event variable ChatListOfNames will be null.

C#
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class ChatService : ISendChatService
    {
        Dictionary<string, IReceiveChatService> names =
        	new Dictionary<string, IReceiveChatService>();

        public static event ListOfNames ChatListOfNames;

        IReceiveChatService callback = null;

        public ChatService() { }

        public void Close()
        {
            callback = null;
            names.Clear();
        }

        public void Start(string Name)
        {
            try
            {
                if (!names.ContainsKey(Name))
                {
                    callback = OperationContext.Current.
                    GetCallbackChannel<IReceiveChatService>();
                    AddUser(Name, callback);
                    SendNamesToAll();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void Stop(string Name)
        {
            try
            {
                if (names.ContainsKey(Name))
                {
                    names.Remove(Name);
                    SendNamesToAll();
                 }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        void SendNamesToAll()
        {
            foreach (KeyValuePair<string, IReceiveChatService> name in names)
            {
                IReceiveChatService proxy = name.Value;
                proxy.SendNames(names.Keys.ToList());
            }

            if (ChatListOfNames != null)
                ChatListOfNames(names.Keys.ToList(), this);
        }

        void ISendChatService.SendMessage(string msg,string sender, string receiver)
        {
            if (names.ContainsKey(receiver))
            {
                callback = names[receiver];
                callback.ReceiveMessage(msg, sender);
           }
        }

        private void AddUser(string name,IReceiveChatService callback)
        {
            names.Add(name, callback);
            if (ChatListOfNames !=null)
                ChatListOfNames(names.Keys.ToList(), this);
        }
    }

Coming to the client, I just implemented the ISendChatService interface. I added two delegates ReceviedMessage and GotNames for ReceiveMsg and NewNames events. The event ReceiveMsg will receive message from any client and the event NewNames will get newly added or deleted client.

C#
public delegate void ReceviedMessage(string sender, string message);
public delegate void GotNames(object sender, List<string /> names);

class ReceiveClient : ChatService.ISendChatServiceCallback
{
    public event ReceviedMessage ReceiveMsg;
    public event GotNames NewNames;

    InstanceContext inst = null;
    ChatService.SendChatServiceClient chatClient = null;

    public void Start(ReceiveClient rc,string name)
    {
        inst = new InstanceContext(rc);
        chatClient = new ChatService.SendChatServiceClient(inst);
        chatClient.Start(name);
    }

    public void SendMessage(string msg, string sender,string receiver)
    {
        chatClient.SendMessage(msg, sender,receiver);
    }

    public void Stop(string name)
    {
        chatClient.Stop(name);
    }

    void ChatService.ISendChatServiceCallback.ReceiveMessage(string msg, string receiver)
    {
        if (ReceiveMsg != null)
            ReceiveMsg(receiver,msg);
    }

    public void SendNames(string[] names)
    {
        if (NewNames != null)
            NewNames(this, names.ToList());
    }
}

Sample Image - maximum width is 600 pixels

Sample Image - maximum width is 600 pixels

In the web config file, I set binding as netTcpBing. Please add your IP in the place of localhost in the baseAddress.

XML
<div>
<configuration>
  <system.serviceModel>
    <services>
      <service name="Server.ChatService"
      behaviorConfiguration="ChatServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:1234/Chat/ChatService"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="netTcpBinding"
        bindingConfiguration="Binding1"
        contract="Server.ISendChatService">
        </endpoint>
        <endpoint address="mex" binding="mexTcpBinding"
        contract="IMetadataExchange"/>
      </service>
    </services>

    <bindings>
      <netTcpBinding>
        <binding name="Binding1" closeTimeout="00:01:00"
        openTimeout="00:01:00" receiveTimeout="00:10:00"
        sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered"
        transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard"
        maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
        maxReceivedMessageSize="65536">
          <security mode="None">
            <message clientCredentialType ="UserName"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="ChatServiceBehavior">
          <serviceMetadata httpGetEnabled="False"/>
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>
</configuration>
</div>

Example Project

The example project consists of three project files. Please install the server on a machine. Compile the solution. Run the server EXE and click start. Update the service in client by right clicking service and click Update Service. After that, you can open many clients.

Conclusion

The webconfig file can be encrypted.

License

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


Written By
Team Leader Quadrantfour Software Solutions Private Limited
India India
I am working in C# and interested in WCF.

Comments and Discussions

 
GeneralThanks for sharing Pin
Member 140036641-Oct-18 2:55
Member 140036641-Oct-18 2:55 
QuestionHelp Me, Implement Client :( Pin
jr0driguezv18-Nov-17 2:48
jr0driguezv18-Nov-17 2:48 
QuestionSpecify reciber Pin
Member 1136235826-Sep-17 12:13
Member 1136235826-Sep-17 12:13 
QuestionClients with different IP Pin
Aya Mena7-Jun-17 12:51
Aya Mena7-Jun-17 12:51 
QuestionEasy to use and simple Pin
Member 1203109310-Feb-17 12:58
Member 1203109310-Feb-17 12:58 
QuestionListener Error Pin
Member 91712708-Dec-15 3:32
Member 91712708-Dec-15 3:32 
AnswerRe: Listener Error Pin
Member 122433434-Jan-16 5:29
Member 122433434-Jan-16 5:29 
QuestionConfirmation of Login Pin
gs_virdi14-Oct-15 1:09
gs_virdi14-Oct-15 1:09 
AnswerFound solution for TCP error code 10061 Pin
bhmi4-Oct-15 20:40
bhmi4-Oct-15 20:40 
Questionwebconfig file? Pin
Psychocrysma29-Sep-15 5:17
Psychocrysma29-Sep-15 5:17 
AnswerRe: webconfig file? Pin
gs_virdi14-Oct-15 1:13
gs_virdi14-Oct-15 1:13 
Look carefully in the solution explorer window, u will find one file app.config in Client, and another file App.config in Server solution. Double click those files and u will find localhost.
Hope this helps.
Questionissue Pin
tanywali3-Aug-14 7:08
tanywali3-Aug-14 7:08 
QuestionChat application in WCF PinPopular
Member 1037749318-Mar-14 8:20
Member 1037749318-Mar-14 8:20 
GeneralPerfect, lightweight and fast Pin
Alan5971012-Feb-14 23:34
Alan5971012-Feb-14 23:34 
QuestionBeautiful solution Pin
Tomas Simonavičius29-Jan-14 2:26
Tomas Simonavičius29-Jan-14 2:26 
QuestionTCP error code 10061 Pin
vin919313-Dec-13 3:41
vin919313-Dec-13 3:41 
AnswerRe: TCP error code 10061 Pin
Member 107356179-Apr-14 4:08
Member 107356179-Apr-14 4:08 
GeneralRe: TCP error code 10061 Pin
parihar9029-Apr-14 19:56
parihar9029-Apr-14 19:56 
Questionproblem Pin
Member 1041429720-Nov-13 10:06
Member 1041429720-Nov-13 10:06 
AnswerRe: problem Pin
Member 1043113827-Nov-13 20:29
Member 1043113827-Nov-13 20:29 
GeneralMy vote of 3 Pin
Member 103017569-Oct-13 4:21
Member 103017569-Oct-13 4:21 
QuestionFTP Pin
Member 1018902111-Aug-13 12:53
Member 1018902111-Aug-13 12:53 
GeneralMy vote of 5 Pin
Carsten V2.018-Jun-13 8:43
Carsten V2.018-Jun-13 8:43 
GeneralRe: My vote of 5 Pin
Kamalakumar24-Jun-13 7:57
Kamalakumar24-Jun-13 7:57 
GeneralRe: My vote of 5 Pin
tanywali3-Aug-14 7:07
tanywali3-Aug-14 7:07 

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.