配置 WCF 端点?聊天服务器和客户端
Configuring WCF Endpoints? Chat server and client
我正在尝试配置客户端程序和聊天服务器程序的 WCF 端点。
当我到达逻辑尝试连接的位置(客户端登录到服务器)时,出现以下错误:
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.
这显然发生在我试图在我的 WPF 聊天客户端中的聊天 window 后面的代码中打开 DuplexChannelFactory 时:
_channelFactory = new DuplexChannelFactory<IChattingService>(new ClientCallback(), "ChattingServiceEndpoint");
我在客户端和服务器的配置文件中都看到了 "ChattingServiceEndpoint" 的 WCF 配置。那么真正缺少的是什么?我是否将 serviceModel 标记放在 app.config 文件的错误部分?我是否需要将其包含在我用来将客户端连接到服务器的 ChattingInterfaces 库的 app.config 中?
这里是客户端和服务器的 app.config 文件。
app.config(服务器):
<?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(客户):
<?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="server=localhost;user id=root;password=abc123;persistsecurityinfo=True;database=otongadgethub"" 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>
这是发生错误的 window 的代码隐藏:
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);
}
}
}
}
}
我愿意 post 更多必要的代码文件来帮助诊断此问题。有人知道 do/what 发生了什么事吗?谢谢!
我又做了一次
我发布了我将归类为 "poofus question." 的结果,配置文件中的端点名称和其他数据区分大小写。确保端点完全匹配,大写和小写逐个字符!
我正在尝试配置客户端程序和聊天服务器程序的 WCF 端点。
当我到达逻辑尝试连接的位置(客户端登录到服务器)时,出现以下错误:
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.
这显然发生在我试图在我的 WPF 聊天客户端中的聊天 window 后面的代码中打开 DuplexChannelFactory 时:
_channelFactory = new DuplexChannelFactory<IChattingService>(new ClientCallback(), "ChattingServiceEndpoint");
我在客户端和服务器的配置文件中都看到了 "ChattingServiceEndpoint" 的 WCF 配置。那么真正缺少的是什么?我是否将 serviceModel 标记放在 app.config 文件的错误部分?我是否需要将其包含在我用来将客户端连接到服务器的 ChattingInterfaces 库的 app.config 中?
这里是客户端和服务器的 app.config 文件。
app.config(服务器):
<?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(客户):
<?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="server=localhost;user id=root;password=abc123;persistsecurityinfo=True;database=otongadgethub"" 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>
这是发生错误的 window 的代码隐藏:
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);
}
}
}
}
}
我愿意 post 更多必要的代码文件来帮助诊断此问题。有人知道 do/what 发生了什么事吗?谢谢!
我又做了一次
我发布了我将归类为 "poofus question." 的结果,配置文件中的端点名称和其他数据区分大小写。确保端点完全匹配,大写和小写逐个字符!