How to create a peer-to-peer chat application using WPF and wcf in Visual Studio 2010


Introduction

In this post, I’ll demonstrate a chat application and provide complete source code and instructions for creating it. It can then serve as a great starting point for being modified to create any sort of peer-to-peer application with a flexible GUI interface.

Each one of those buzzwords in the title is important for this post, and I’ve tried to include enough information for this to be a helpful introduction to any one of them:

  • Peer-to-peer: No centralized server is required. each individual node in the chat network acts as its own client and server for communicating with its neighbors.
  • WPF (Windows Presentation Foundation): This is the library that will provide all the GUI elements (window, textbox, etc.) and handles the user interaction events (keystrokes, mouse clicks, etc.).
  • WCF (Windows Communication Foundation): This is the library we’ll use for all the networking functionality.
  • Visual Studio 2010: In principle, you could create this program in any development environment, but I’ll show you all the right buttons to press in Visual Studio, and we’ll take advantage of the GUI builder (the design view for WPF) and the features for specifying WPF and WCF code via XML.

Our application will consist of a single Visual Studio solution that contains two projects [see “Introduction to Solutions, Projects, and Items”]. The first project we’ll create will define the GUI front-end and the second will define all the application logic and networking functionality.

 

The GUI Front End

To begin, open Visual Studio 2010 and go to “File –> New –> Project”.

Use the “WPF Application” template to create a project with the name “ChatGUI” inside a new solution named “Chat”, as seen here:

WPF Template

The WPF Application template will open to a GUI builder (“designer mode” view) of a file called MainWindow.xaml [see “XAML Overview” ]. Click the “Toolbox” tab on the left side of the screen to expand the view of GUI elements, and drag two TextBox controls onto the screen. We’ll use one of the TextBox widgets to be the display screen where we see all the text written by our friends during a chat session, and we’ll use the other TextBox as the entry field for adding to the chat conversation. Rather than adding a submit button, we’ll just pay attention to the Enter key when a user is typing in the entry field. There are also plenty of other interesting controls, and we may come back in a later post to demonstrate some of them, like the RichTextBox for display formatted text with colors and images interspersed [see “WPF Controls” ].

MainWindow.xaml 1

Next, in the XAML editing pane on the bottom portion of the screen, let’s adjust the size, placement, and names of our TextBox elements, by changing the XAML code to read:

Listing 1: MainWindow.xaml
<Window x:Class="ChatGUI.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="35*" />
            <RowDefinition Height="35" />
        </Grid.RowDefinitions>
        <TextBox Height="Auto" HorizontalAlignment="Stretch" Margin="6,6,6,6" Name="textBoxChatPane" VerticalAlignment="Stretch" Width="Auto" Grid.Row="0" />
        <TextBox Height="23" HorizontalAlignment="Stretch" Margin="6,6,6,6" Name="textBoxEntryField" VerticalAlignment="Stretch" Width="Auto" Grid.Row="1" KeyDown="textBoxEntryField_KeyDown" />
    </Grid>
</Window>

If you type this in manually (as opposed to cutting and pasting the whole thing), you’ll notice the editor’s Intellisense features helping you. For example, fields like HorizontalAlignment have a finite number of values that you can choose from. Similarly, there are a predefined set of events that a TextBox can respond to. We’ve chosen to bind the “KeyDown” event on the “textBoxEntryField” to a new method, and in fact I even let Visual Studio choose the name of that method for me (as you type KeyDown=””, a drop-down box appears, allowing you to select <New Event Handler>). Now click on the MainWindow.xaml.cs tab. This brings us to the C# “code-behind” for the GUI. Notice that an empty textBoxEntryField_KeyDown method has already been created for us in the MainWindow class (you can also get to this by highlighting “textBoxEntryField_KeyDown” in the XAML editor window, clicking the right mouse button, and choosing “Navigate to Event Handler”).

At this point, you’ve already created enough code to build the application and pop up a GUI window. Try it out by hitting F5, and confirm that everything builds without errors, and when it runs a new window appears that looks something like this:

image

Assuming that worked, great. Now kill your application, either by closing the window or by hitting shift-F5 back in Visual Studio.

By the time we’re done, our MainWindow.xaml.cs code will have three methods: the MainWindow constructor, the textBoxEntryField_KeyDown event handler, and a DisplayMessage method that we’ll use for displaying text in the textBoxChatPane widget. We’ll also have one private member variable that will act as a handle to an object that represents all the back-end functionality. But before we go any further on the GUI implementation, let’s switch gears and create the back-end system.

 

The Back End Communication System

In the Solution Explorer pane, right-click the “Solution ‘Chat’” line, and go to “Add –> New Project… –> Class Library” and call the new project ChatBackend.

image

This project is going to contain all the communication code, and we could have used one of the WCF templates instead of just a generic C# class library – these are worth playing around with, and are perfect for creating a client/server app, but none of them happen to be exactly suited for the peer-to-peer configuration we’re going to create, so we’ll do it by hand.

In this project, we’ll end up with two C# files: the IChatBackend interface that defines the set of methods to be supported by a backend implementation, and the ChatBackend class with the actual logic. First we’ll create the interface. Right-click on “ChatBackend” in the Solution Explorer pane, and select “Add –> New Item –> Interface” and call it IChatBackend.cs.

image

Before you start typing in code for IChatBackend.cs, you should add the necessary references. We’ll be using WCF libraries, and you will need to specify references to System.ServiceModel and System.Runtime.Serialization. In the Solution Explorer pane, right-click on the References node under the ChatBackend project. Go to “Add Reference…”, click on the .NET tab, and add System.ServiceModel, then repeat the process for System.Runtime.Serialization.

In this code, we’ll say that any class which implements the IChatBackend interface has to define two methods: DisplayMessage and SendMessage. You can think of the usage of DisplayMessage in a remote procedure call sort of way – our friends on the peer-to-peer network will call our DisplayMessage method when they want us to display something. We will use our own SendMessage method the call the DisplayMessage methods owned by all of our friends.

We’ll say that DisplayMessage does not return any values, and is a OneWay communication mechanism (we tell our friends to display something, but they don’t have to respond).

In this file, we’ll also define a class called CompositeType, which is capable of holding two string values (a username and a message), and we’ll say that the DisplayMessage method should always be called with one of these CompositeType objects. This is not strictly necessary – we could have simply defined DisplayMessage to take two strings – but when you start to build on this application to send more complicated data objects over the network, the CompositeType will come in handy.

Lastly, we’ll define a delegate type DisplayMessageDelegate. This exists to help us separate the GUI code from the application logic and communication code. The idea is that the GUI will have some mechanism for showing a message on the screen, but the backend shouldn’t have to be aware of the implementation details. When we start up the system, the GUI code will use delegates to pass a function handle to the backend, which can be called whenever the backend wants the GUI to display a message to the user.

All of the code described above is shown here in the listing for IChatBackend.cs:

Listing 2: IChatBackend.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace ChatBackend
{
    [ServiceContract]
    public interface IChatBackend
    {
        [OperationContract(IsOneWay = true)]
        void DisplayMessage(CompositeType composite);

        void SendMessage(string text);
    }

    [DataContract]
    public class CompositeType
    {
        private string _username = "Anonymous";
        private string _message = "";

        public CompositeType() { }
        public CompositeType(string u, string m)
        {
            _username = u;
            _message = m;
        }

        [DataMember]
        public string Username
        {
            get { return _username; }
            set { _username = value; }
        }

        [DataMember]
        public string Message
        {
            get { return _message; }
            set { _message = value; }
        }
    }

    public delegate void DisplayMessageDelegate(CompositeType data);
}

 

The next step is to create the implementation of our ChatBackend. When we created the ChatBackend project, it generated an empty Class1.cs file, which you can “File –> Save Class1.cs As…” ChatBackend.cs to rename it.

The ChatBackend class will have the following methods inside it:

  • A constructor that takes a DisplayMessageDelegate as an argument. As discussed above, this delegate is a callback that allows the backend to request that something be displayed in the GUI, without having to know anything about the GUI implementation.
  • DisplayMessage(), which calls the DisplayMessageDelegate.
  • SendMessage(), which uses the communication channel to call the DisplayMessage() methods provided by each of our friends.
  • StartService(), which is required as part of the WCF code to create the communication channel.
  • StopService(), which closes the communication channel gracefully.

Here’s the code for the implementation:

 

Listing 3: ChatBackend.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace ChatBackend
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class ChatBackend : IChatBackend
    {

        #region Everything we need to receive messages

        DisplayMessageDelegate _displayMessageDelegate = null;

        /// <summary>
        /// The default constructor is only here for testing purposes.
        /// </summary>
        private ChatBackend()
        {
        }

        /// <summary>
        /// ChatBackend constructor should be called with a delegate that is capable of displaying messages.
        /// </summary>
        /// <param name="dmd">DisplayMessageDelegate</param>
        public ChatBackend(DisplayMessageDelegate dmd)
        {
            _displayMessageDelegate = dmd;
            StartService();
        }

        /// <summary>
        /// This method gets called by our friends when they want to display a message on our screen.
        /// We're really only returning a string for demonstration purposes ... it might be cleaner
        /// to return void and also make this a one-way communication channel.
        /// </summary>
        /// <param name="composite"></param>
        public void DisplayMessage(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (_displayMessageDelegate != null)
            {
                _displayMessageDelegate(composite);
            }
        }

        #endregion // Everything we need to receive messages

        #region Everything we need for bi-directional communication

        private string _myUserName = "Anonymous";
        private ServiceHost host = null;
        private ChannelFactory<IChatBackend> channelFactory = null;
        private IChatBackend _channel;

        /// <summary>
        /// The front-end calls the SendMessage method in order to broadcast a message to our friends
        /// </summary>
        /// <param name="text"></param>
        public void SendMessage(string text)
        {
            if (text.StartsWith("setname:", StringComparison.OrdinalIgnoreCase))
            {
                _myUserName = text.Substring("setname:".Length).Trim();
                _displayMessageDelegate(new CompositeType("Event", "Setting your name to " + _myUserName));
            }
            else
            {
                // In order to send a message, we call our friends' DisplayMessage method
                _channel.DisplayMessage(new CompositeType(_myUserName, text));
            }
        }

        private void StartService()
        {
            host = new ServiceHost(this);
            host.Open();
            channelFactory = new ChannelFactory<IChatBackend>("ChatEndpoint");
            _channel = channelFactory.CreateChannel();

            // Information to send to the channel
            _channel.DisplayMessage(new CompositeType("Event", _myUserName + " has entered the conversation."));

            // Information to display locally
            _displayMessageDelegate(new CompositeType("Info", "To change your name, type setname: NEW_NAME"));
        }

        private void StopService()
        {
            if (host != null)
            {
                _channel.DisplayMessage(new CompositeType("Event", _myUserName + " is leaving the conversation."));
                if (host.State != CommunicationState.Closed)
                {
                    channelFactory.Close();
                    host.Close();
                }
            }
        }


        #endregion // Everything we need for bi-directional communication

    }
}

 

Now that we have the ChatBackend in place, let’s go back to the GUI code to wire everything together.

The GUI contains code that will be instantiating a ChatBackend object and calling its methods, so the ChatGUI project will need to contain a reference to the ChatBackend project. Specify this by right-clicking the References item under the ChatGui project in the Solution Explorer. Select “Add Reference…” and in the Projects tab, select ChatBackend.

Now start editing MainWindow.xaml.cs under the ChatGui project. We’ll need a private member variable to keep a reference to a ChatBackend object, and we’ll need to fill out the constructor, the event handler and the DisplayMessage methods.

Here’s the resulting source code:

Listing 4: MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ChatGUI
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ChatBackend.ChatBackend _backend;

        public MainWindow()
        {
            InitializeComponent();
            _backend = new ChatBackend.ChatBackend(this.DisplayMessage);
        }

        public void DisplayMessage(ChatBackend.CompositeType composite)
        {
            string username = composite.Username == null ? "" : composite.Username;
            string message = composite.Message == null ? "" : composite.Message;
            textBoxChatPane.Text += (username + ": " + message + Environment.NewLine);
        }

        private void textBoxEntryField_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Return || e.Key == Key.Enter)
            {
                _backend.SendMessage(textBoxEntryField.Text);
                textBoxEntryField.Clear();
            }
        }
    }
}

 

The WCF Configuration File

This is all the C# source code that we’ll need for our application, but we have on last missing piece, which is that we need to create a configuration file that will tell WCF how to behave. For background information on the configuration file we’re about to create, see “Windows Communication Foundation Configuration Schema” and  “Configuration Editor Tool (SvcConfigEditor.exe)” .

In Visual Studio, go to “Tools –> WCF Service Configuration Editor”. This will launch the configuration editor in a new window. Select “File –> New Config” to bring up an empty configuration, which should look something like this:

image

Select “Create a New Service” from the right-hand pane.

The “Service type” should be ChatBackend.ChatBackend

The “Service contract” should be ChatBackend.IChatBackend

Select “Peer to Peer” as the communication mode.

The address for the endpoint should be: net.p2p://Chat

image

image

Next, click on “Endpoint: (Empty Name)” and give the endpoint the name “Chat”

image

At this point, you should save the configuration into <your projects directory>\Chat\ChatGUI\App.config (where <your projects directory> is typically something like C:\Users\username\Documents\Visual Studio 2010\Projects).

Now, continuing in the configuration editor, let’s create a client. Since this is a peer-to-peer application, our program acts as both a service provider and a client for that same service.

In the left-hand Configuration pane, click on “Client”, and then in the right-hand pane, “Create a New Client”. We’ll want to create a client based on the service configuration we’ve already created, so in the “Generate a client config from the config of the service” field, browse to this same configuration file that you just saved, and click Next.

There should be just one service endpoint to select (the ChatBackend.ChatBackend endpoint), and name your Client configuration ChatEndpoint.

image

Last, we’ll need to define the bindings. Click on “Bindings” in the left-hand pane, followed by “Create New Binding” and select the netPeerTcpBinding type. Change the binding configuration name to be “Wimpy” (because we’ll start with something completely unsecure… later we can come back and require different varieties of authentication).

On the Security tab for this binding, choose Mode: None. Then in the left-hand pane, under Bindings –> Wimpy –> resolver, click “resolver” and set Mode to be Pnrp.

Now go back to “Services –> ChatBackend.ChatBackend –> Endpoints –> Chat” in the left-hand pane and set BindingConfiguration to be “Wimpy”.

Do the same for “Client –> Endpoints –> ChatEndpoint –> BindingConfiguration”

Finally, save and close the Configuration window.

Next, in the Solution Explorer, right-click on the ChatGUI project, select Add Existing Item, and add the App.config file to the project (you’ll have to change the file filters to allow all file types in order to browse to it).

Double-click the App.config file in order to double-check the work that was done by the configuration editor. You should see the following XML code. If it isn’t quite right, you can always fix it up by hand:

Listing 5: App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.serviceModel>
        <bindings>
            <netPeerTcpBinding>
                <binding name="Wimpy">
                    <resolver mode="Pnrp" />
                    <security mode="None">
                        <transport credentialType="Password" />
                    </security>
                </binding>
            </netPeerTcpBinding>
        </bindings>
        <client>
            <endpoint address="net.p2p://Chat" binding="netPeerTcpBinding"
                bindingConfiguration="Wimpy" contract="ChatBackend.IChatBackend"
                name="ChatEndpoint" kind="" endpointConfiguration="">
                <identity>
                    <certificateReference storeName="My" storeLocation="LocalMachine"
                        x509FindType="FindBySubjectDistinguishedName" />
                </identity>
            </endpoint>
        </client>
        <services>
            <service name="ChatBackend.ChatBackend">
                <endpoint address="net.p2p://Chat" binding="netPeerTcpBinding"
                    bindingConfiguration="Wimpy" name="Chat" contract="ChatBackend.IChatBackend" />
            </service>
        </services>
    </system.serviceModel>
</configuration>

Now we’re done!

Let’s build and run the final program.

To do so, hit F5 in Visual Studio.

Since the program will try to establish a service that listens on a port, you’ll see a security dialog like the following:

image

Click the “Allow Access” button.

Then, because a chat application isn’t any fun without at least two instances, run another copy. you can browse to the program and run it by double-clicking <your projects folder>\Chat\ChatGUI\bin\Debug\ChatGUI.exe

And we have two chat windows open that can talk to each other:

 image


Comments (41)
  1. AnhDNV says:

    hi sleibman, i tested it on WindowXp and Window 7, sometime it's not working correctly on Window 7, but i cant find reason, on Xp and Vista, it's work correctly

  2. Mike Richards says:

    Hey, I'm trying out this code on Win7 and, upon compiling, I'm consistently getting the following exception:

    System.Windows.Markup.XamlParseException was unhandled

     Message='The invocation of the constructor on type 'ChatGUI.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'.

     Source=PresentationFramework

     LineNumber=3

     LinePosition=9

     StackTrace:

          at System.Windows.Markup.XamlReader.RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)

          at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)

          at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)

          at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)

          at System.Windows.Application.LoadBamlStreamWithSyncInfo(Stream stream, ParserContext pc)

          at System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean bSkipJournaledProperties)

          at System.Windows.Application.DoStartup()

          at System.Windows.Application.<.ctor>b__1(Object unused)

          at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)

          at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

          at System.Windows.Threading.DispatcherOperation.InvokeImpl()

          at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)

          at System.Threading.ExecutionContext.runTryCode(Object userData)

          at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)

          at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)

          at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)

          at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

          at System.Windows.Threading.DispatcherOperation.Invoke()

          at System.Windows.Threading.Dispatcher.ProcessQueue()

          at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)

          at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)

          at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)

          at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)

          at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

          at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)

          at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)

          at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)

          at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)

          at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)

          at System.Windows.Threading.Dispatcher.Run()

          at System.Windows.Application.RunDispatcher(Object ignore)

          at System.Windows.Application.RunInternal(Window window)

          at System.Windows.Application.Run(Window window)

          at System.Windows.Application.Run()

          at ChatGUI.App.Main() in c:usersmikedocumentsvisual studio 2010ProjectsChatChatGUIobjx86DebugApp.g.cs:line 0

          at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)

          at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)

          at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()

          at System.Threading.ThreadHelper.ThreadStart_Context(Object state)

          at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)

          at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

          at System.Threading.ThreadHelper.ThreadStart()

     InnerException: System.InvalidOperationException

          Message=Cannot load the X.509 certificate identity specified in the configuration.

          Source=System.ServiceModel

          StackTrace:

               at System.ServiceModel.Description.ConfigLoader.LoadIdentity(IdentityElement element)

               at System.ServiceModel.Description.ConfigLoader.LoadChannelBehaviors(ServiceEndpoint serviceEndpoint, String configurationName)

               at System.ServiceModel.ChannelFactory.ApplyConfiguration(String configurationName, Configuration configuration)

               at System.ServiceModel.ChannelFactory.ApplyConfiguration(String configurationName)

               at System.ServiceModel.ChannelFactory.InitializeEndpoint(String configurationName, EndpointAddress address)

               at System.ServiceModel.ChannelFactory`1..ctor(String endpointConfigurationName, EndpointAddress remoteAddress)

               at System.ServiceModel.ChannelFactory`1..ctor(String endpointConfigurationName)

               at ChatBackend.ChatBackend.StartService() in c:usersmikedocumentsvisual studio 2010ProjectsChatChatBackendChatBackend.cs:line 64

               at ChatBackend.ChatBackend..ctor(DisplayMessageDelegate dmd) in c:usersmikedocumentsvisual studio 2010ProjectsChatChatBackendChatBackend.cs:line 24

               at ChatGUI.MainWindow..ctor() in c:usersmikedocumentsvisual studio 2010ProjectsChatChatGUIMainWindow.xaml.cs:line 27

          InnerException:

    Any ideas?  I'm stumped.

  3. Mike Richards says:

    Hey, I'm trying out this code on Win7 and, upon compiling, I'm consistently getting the following exception:

    System.Windows.Markup.XamlParseException was unhandled

     Message='The invocation of the constructor on type 'ChatGUI.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'.

  4. Mike Richards says:

    A little more detail:

    The project build successfully earlier, when it was just the raw WPF application, displaying only the text boxes.  However, once everything else was added in, this compile error is thrown.

  5. Barbi Salazar says:

    Does this project works across the Internet

  6. adarsh says:

    Hi can we implement same for group chat application

  7. Iadh says:

    everything works so fine until i allowed the access to the application in the end it runs an exception :

    'The invocation of the constructor on type 'ChatGUI.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'.

    anybody knows what this means please contact me at keepsmile@hotmail.fr

    thanks

  8. Ray says:

    I get that same error

    'The invocation of the constructor on type 'ChatGUI.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'.

    but i get this error when i try run the app

    Can anybody help me with this ?

  9. NFK says:

    I get exactly the same error (XamlParseException). Perhaps this should be addressed soon?

    It seems to occur when serviceHost.Open() is called. It throws System.InvalidOperationException when I catch it.

    Other than that, great guide.

  10. Robert says:

    Hey man, im following your tutorial as we speak, but i get the following error halfway

    Class1.Class1'  does not implement interface member 'Class1,Interface1.Sendmessage(string)'

    any idea on how to solve this?

    thanks !

  11. john says:

    Someone here fix the error?

    'The invocation of the constructor on type 'ChatGUI.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'.

  12. Toral says:

    Comment out following code

    <!–<identity>

             <certificateReference storeName="My" storeLocation="LocalMachine"

                 x509FindType="FindBySubjectDistinguishedName" />

           </identity>–>

  13. PREM says:

    The invocation of the constructor on type 'ChatGUI.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'.

  14. Peyman says:

    I also have the same problem with this error:

    Additional information: 'The invocation of the constructor on type 'ChatGUI.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'.

    I know that no one answered this yet!

  15. Andrew says:

    To all having the line number 3 and line position 9 problems follow this advice from Toral:

    Comment out following code

    <!–<identity>

            <certificateReference storeName="My" storeLocation="LocalMachine"

                x509FindType="FindBySubjectDistinguishedName" />

          </identity>–>

  16. sonal says:

    Cannot create instance of 'Window1' defined in assembly 'ChatGUI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Exception has been thrown by the target of an invocation.  Error in markup file 'Window1.xaml' Line 1 Position 9.

    i got this error

  17. Timm says:

    Or do this:

    <identity>

    <dns value="localhost" />  <!– ADD THIS LINE IF MISSING –>

    <certificateReference storeName="My" storeLocation="LocalMachine"

    x509FindType="FindBySubjectDistinguishedName" />

    </identity>

  18. V G S Naidu says:

    hai,

    It's working fine when i open the to windows in my won Pc…

    But,

    when i install it in another system it didn't recognize the network attached pc's and didn't communicate with them from my system…

    how to chat to the particular system using my be with port or ip address…

    please provide the source to implement this please

  19. Arsh says:

    Hi All,

    You can check my WPF and Silverlight 5 Chat Appliaction(partially complete) at:

    iconnect.arshdeep-virdi.com/web

    This application is using net.tcp protocol to connect to the WCF service. Also you can download the fully functional WPF client for testing.

    Regards,

    Arsh

  20. Vinith says:

    Hi all,

    i commented the lines that Toral told… but i get the same error….

    'The invocation of the constructor on type 'ChatGUI.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'.

    Any ided

    Regards,

    Vinith

  21. vinith says:

    Hi,

    The invocation of the constructor on type 'ChatGUI.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'.

    help me to resolve this error..

    Contact me at rvinith.siva@gmail.com

  22. Pulkit Gulati says:

    Hi,

    I have tried making this application using winForms and it works really well…. getting the same xamlparseexception in WPF though…. please let me know if anybody knows the solution to this exception….

  23. Joey says:

    It can't find "ServiceBehaviour" and "ServiceModel" …… from IChatBackend and ChatBackend…. any help? e-mail please at Prodigetukala@hotmail.co.uk

  24. Mr B Jobs says:

    i cant find the download source button???

  25. Corentin says:

    Hi everyone

    I think i solved the xamlparseexception !

    go into the StartService method and change "ChatEndpoint" to "ChatEndPoint"

  26. javascript:WebForm_DoPostBackWithOptions(new%20WebForm_PostBackOptions("ctl00$content$ctl00$w_52320$_ae2cd5$ctl00$ctl00$ctl00$ctl05$bpCommentForm$ctl05$btnSubmit",%20"",%20true,%20"BlogPostCommentForm-ctl00_content_ctl00_w_52320__ says:

    javascript:WebForm_DoPostBackWithOptions(new%20WebForm_PostBackOptions("ctl00$content$ctl00$w_52320$_ae2cd5$ctl00$ctl00$ctl00$ctl05$bpCommentForm$ctl05$btnSubmit",%20"",%20true,%20"BlogPostCommentForm-ctl00_content_ctl00_w_52320__ae2cd5_ctl00_ctl00",%20"",%20false,%20true))

  27. Vinay says:

    hello, I was trying to implement this code but it gives an error in DisplayMessageDelegate _displayMessageDelegate = null; in ChatBackend.cs file. Even I did not get this, we are no where creating the DisplayMessageDelegate class.

  28. SuDT says:

    Do we have a solution for 'The invocation of the constructor on type " exception? Commenting out the identity section or changing ChatEndpoint to ChatEndPoint did not help.

  29. Anonymous says:

    Yes, I was getting the 'The invocation of the constructor on type 'ChatGUI.MainWindow' error too but luckily resolved it. Go to App.config file and make sure that the endpoint address="net.p2p://chat" for both the client and service. If they are different, then it means that the client and service are trying to communicate on two different addresses. Also note the Client Endpoint name in App.config. It should be "ChatEndPoint". Make sure that it is the same in ChatBackend.cs in the statement "channelFactory = new ChannelFactory<IChatBackend>("ChatEndPoint"); ". If they are not same, then it is an error because the client and service have two different endpoints. Hence, the service is looking for an endpoint that does not actually exist. This is why Visual Studio is throwing an error.

  30. Kannan says:

    Which Shows this error…

    ChatGUI.exe' does not contain a static 'Main' method suitable for an entry point

  31. Anonymous 1 says:

    I'm trying to make the same in VS2013, everything looks fine, but it underlines "_backend" in "_backend = new ChatBackend.ChatBackend(this.DisplayMessage);" saying that "The name '_backend' does not exist in the current context". What is wrong?

  32. raza mehdi says:

    hello i have run the app successfully but when i run the .exe on other pc then my messages were not showing on that pc nor the messages on written on that pc are showing on mine. how to correct this so i can use this app on different computers using the same network. please reply asap.

  33. Trying says:

    I cannot find the WCF Service Configuration Editor under tools it doesnt exist

  34. Gertrud Anger says:

    Everything is wrong, no matter how carefully I make it from here http://noiamarkmik.net/grr.jpg

  35. Mayank says:

    Is it mandatory to set endpoint address="net.p2p://Chat"

    can i use different address like tcp://(localhost)……   something like this ?

  36. BinayRam says:

    everything works so fine until i allowed the access to the application in the end it runs an exception :

    'The invocation of the constructor on type 'ChatGUI.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'.

    anybody knows what this means please contact me at r.binayram@gmail.com

    thanks

  37. Hannes says:

    definitly wrong…

    you should had post the source code….

    with that.. Zero Points

  38. Joce says:

    If that can help for people that still have the error: 'The invocation of the constructor on type 'ChatGUI.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'.

    I found that I didn't set in the WCF configurator the security to none: On the Security tab for this binding, choose Mode: None. Then in the left-hand pane, under Bindings –> Wimpy –> resolver, click “resolver” and set Mode to be Pnrp.

    I also commented <!–<identity>

             <certificateReference storeName="My" storeLocation="LocalMachine"

               x509FindType="FindBySubjectDistinguishedName" />

           </identity>–>

  39. Prince says:

    thanks, it got me sometime but it correctly worked for after solving some problems.

  40. Siddharth Mishra says:

    The exception "Line number '3'…." is due to exception occurred at "StartService()" method where we are creating an object of Channel from ClientEndPoint.

    Adding <dns value="localhost"/> inside <identity></identity> tag will fix it.

    stackoverflow.com/…/cannot-load-the-x-509-certificate-identity-specified-in-the-configuration

  41. sarita algeriana says:

    everything works so fine until i allowed the access to the application in the end it runs an exception :

    'The invocation of the constructor on type 'ChatGUI.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'.

    anybody knows what this means please contact me at djekidel.sara@gmail.com

    thanks

Comments are closed.

Skip to main content