Search code examples
c#wpfwcf.net-4.5nettcpbinding

Configuring WCF Endpoints? Chat server and client


I'm trying to configure the WCF endpoints of my client program and my chat server program.

When I get to the point where the logic is trying to connect (client login to server), I get the following error:

Could not find endpoint element with name 'ChattingServiceEndpoint' and contract 'ChattingInterfaces.IChattingService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this name could be found in the client element.

This apparently happens while I am trying to open a DuplexChannelFactory in the code behind of the chat window in my WPF Chat Client:

_channelFactory = new DuplexChannelFactory<IChattingService>(new ClientCallback(), "ChattingServiceEndpoint");

I see the WCF configurations for the "ChattingServiceEndpoint" in BOTH the config files of both the client and the server. So what's really missing? Did I put the serviceModel tag in the wrong section of the app.config file? Do I need to include it in the app.config of the ChattingInterfaces library I am using to connect the client to the server?

Here the app.config file for the client and server.

app.config(server):

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <system.serviceModel>
    <services>
      <service name="ChattingServer.ChattingService">
        <endpoint address="net.tcp://localhost:9000/ChattingService" binding="netTcpBinding" bindingConfiguration="" name="ChattingServiceEndPoint" contract="ChattingInterfaces.IChattingService" />
      </service>
    </services>
  </system.serviceModel>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="MySql.Data" publicKeyToken="c5687fc88969c44d" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-6.8.7.0" newVersion="6.8.7.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <system.data>
    <DbProviderFactories>
      <remove invariant="MySql.Data.MySqlClient" />
      <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.8.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
    </DbProviderFactories>
  </system.data>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

app.config(client):

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>

    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="MySql.Data" publicKeyToken="c5687fc88969c44d" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-6.8.7.0" newVersion="6.8.7.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
<connectionStrings><add name="otongadgethubEntities" connectionString="metadata=res://*/OTonGadgetHub.csdl|res://*/OTonGadgetHub.ssdl|res://*/OTonGadgetHub.msl;provider=MySql.Data.MySqlClient;provider connection string=&quot;server=localhost;user id=root;password=abc123;persistsecurityinfo=True;database=otongadgethub&quot;" providerName="System.Data.EntityClient" /></connectionStrings>
  <system.serviceModel>
    <client>
      <endpoint address="net.tcp://localhost:9000/ChattingService" binding="netTcpBinding" bindingConfiguration="" contract="ChattingInterfaces.IChattingService" name="ChattingServiceEndPoint" kind="" endpointConfiguration="" />
    </client>
  </system.serviceModel>
<system.data>
    <DbProviderFactories>
      <remove invariant="MySql.Data.MySqlClient" />
      <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.8.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
    </DbProviderFactories>
  </system.data></configuration>

Here's the codebehind for the window where the error occurs:

using ChattingInterfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
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.Shapes;

namespace ChatClient
{
    /// <summary>
    /// Interaction logic for ChatWPFClient.xaml
    /// </summary>
    public partial class ChatWPFClient : Window
    {
        //our current logged in user that will be set at MainWindow at login
        public static user loggedInUser;

        public static IChattingService Server;
        private static DuplexChannelFactory<IChattingService> _channelFactory;
        public ChatWPFClient()
        {
            InitializeComponent();
            _channelFactory = new DuplexChannelFactory<IChattingService>(new ClientCallback(), "ChattingServiceEndpoint");
            Server = _channelFactory.CreateChannel();

            int returnValue = Server.Login(loggedInUser.username);
            if (returnValue == 1)
            {
                MessageBox.Show("You are already logged in, check to see who is logged into system");

            }
            else if (returnValue == 0)
            {
                MessageBox.Show("You are now logged in! Welcome!");
                welcomeLabel.Text = "Welcome, " + loggedInUser.username;

            }
        }

        private void sendMessage(object sender, RoutedEventArgs e)
        {
            //MessageBox.Show("Not available yet!");

            //TODO: Change username
            if (chatEntryField.Text.Length == 0)
            {
                return;
            }
            Server.SendMessageToALL(chatEntryField.Text, "Test");
            TakeMessage(chatEntryField.Text, "Test");
            chatEntryField.Text = "";
        }

        public void TakeMessage(string message, string userName)
        {
            chatBox.Text += userName + ": " + message + "\n";
            //TODO: Scroll chatBox to end
        }
    }
}

IChattingService.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace ChattingInterfaces
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IChattingServices" in both code and config file together.
    [ServiceContract(CallbackContract=typeof(IClient))]
    public interface IChattingService
    {
        [OperationContract]
        int Login(string userName);
        [OperationContract]
        void SendMessageToALL(string message, string userName);
    }
}

ChattingService.cs:

using ChattingInterfaces;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace ChattingServer
{
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
    public class ChattingService : IChattingService
    {
        //private ConnectedClient _connectedClients;

        public ConcurrentDictionary<string, ConnectedClient> _connectedClients = new ConcurrentDictionary<string, ConnectedClient>();

        public int Login(string userName)
        {
            //is anyone else logged in with my name?
            foreach (var client in _connectedClients)
            {
                if(client.Key.ToLower() == userName.ToLower())
                {
                    //if yes
                    return 1;
                }
            }

            var establishedUserConnection = OperationContext.Current.GetCallbackChannel<IClient>();

            ConnectedClient newClient = new ConnectedClient();
            newClient.connection = establishedUserConnection;
            newClient.UserName = userName;



            _connectedClients.TryAdd(userName, newClient);

            return 0;
        }


        public void SendMessageToALL(string message, string userName)
        {
            foreach (var client in _connectedClients)
            {
                if (client.Key.ToLower() != userName.ToLower())
                {
                    client.Value.connection.GetMessage(message, userName);
                }
            }
        }
    }
}

I am willing to post more code files as necessary to help diagnose this problem. Anyone got an idea of what to do/what's going on? Thanks!


Solution

  • I did it again.

    I posted what I would classify as a "poofus question." Turns out that the endpoint names and other data in the config files are case sensitive. Make sure the endpoints match EXACTLY, character by character in both upper and lower case!