一、WCF 技术概述
Windows Communication Foundation (WCF) 是微软推出的统一编程模型,用于构建分布式应用程序。它整合了早期的分布式通信技术(如.NET Remoting、Web Services 等),提供了跨平台、跨协议的通信能力。WCF 的核心优势包括:
- 支持多种传输协议(HTTP、TCP、Named Pipes 等)
- 提供多种消息编码格式(文本、二进制、MTOM)
- 内置完善的安全机制(身份验证、授权、加密)
- 支持多种服务托管方式(IIS、Windows 服务、控制台应用等)
二、系统架构设计
我们要实现的系统包含两个客户端和一个服务端:
- Client1:定义远程接口并实现服务逻辑
- Client2:通过 WCF 调用 Client1 提供的服务
- ServiceHost:托管服务,实现 Client1 和 Client2 之间的通信
系统架构图:
+-----------+ +-------------+ +-----------+
| Client2 | --> | ServiceHost| <-- | Client1 |
+-----------+ +-------------+ +-----------+
调用服务 消息中继 实现服务
三、接口定义与服务实现
首先需要定义远程接口和数据契约:
// 定义数据契约
[DataContract]
public class DataItem
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public DateTime Timestamp { get; set; }
}
// 定义远程接口
[ServiceContract]
public interface IDataService
{
[OperationContract]
List<DataItem> GetDataItems();
[OperationContract]
void AddDataItem(DataItem item);
[OperationContract]
DataItem GetDataItemById(int id);
}
Client1 需要实现这个接口:
// Client1实现服务接口
public class DataService : IDataService
{
private readonly List<DataItem> _dataItems = new List<DataItem>();
public List<DataItem> GetDataItems()
{
return _dataItems;
}
public void AddDataItem(DataItem item)
{
item.Timestamp = DateTime.Now;
_dataItems.Add(item);
}
public DataItem GetDataItemById(int id)
{
return _dataItems.FirstOrDefault(i => i.Id == id);
}
}
四、服务配置与托管
Client1 需要创建并启动服务主机:
// Client1 - 启动服务主机
class Program
{
static void Main(string[] args)
{
// 创建服务主机
using (ServiceHost host = new ServiceHost(typeof(DataService)))
{
// 添加服务端点
host.AddServiceEndpoint(
typeof(IDataService),
new NetTcpBinding(),
"net.tcp://localhost:8080/DataService");
// 添加元数据交换端点
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
// 启动服务
host.Open();
Console.WriteLine("服务已启动,按任意键停止...");
Console.ReadKey();
// 关闭服务
host.Close();
}
}
}
五、客户端访问实现
Client2 需要创建服务代理并调用服务:
// Client2 - 调用服务
class Program
{
static void Main(string[] args)
{
// 创建服务代理
ChannelFactory<IDataService> factory = new ChannelFactory<IDataService>(
new NetTcpBinding(),
new EndpointAddress("net.tcp://localhost:8080/DataService"));
IDataService proxy = factory.CreateChannel();
try
{
// 添加数据项
proxy.AddDataItem(new DataItem { Id = 1, Name = "Item 1" });
proxy.AddDataItem(new DataItem { Id = 2, Name = "Item 2" });
// 获取所有数据项
List<DataItem> items = proxy.GetDataItems();
Console.WriteLine("获取到的数据项:");
foreach (var item in items)
{
Console.WriteLine($"ID: {item.Id}, Name: {item.Name}, Time: {item.Timestamp}");
}
// 通过ID获取数据项
DataItem itemById = proxy.GetDataItemById(1);
Console.WriteLine($"通过ID获取的数据项: {itemById.Name}");
}
catch (Exception ex)
{
Console.WriteLine($"调用服务时发生错误: {ex.Message}");
}
finally
{
// 关闭代理
((IClientChannel)proxy).Close();
factory.Close();
}
Console.WriteLine("按任意键退出...");
Console.ReadKey();
}
}
六、配置文件设置
服务端和客户端都需要适当的配置文件:
服务端配置 (app.config):
<configuration>
<system.serviceModel>
<services>
<service name="Client1.DataService">
<endpoint address=""
binding="netTcpBinding"
contract="Common.IDataService" />
<endpoint address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8080/DataService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
客户端配置 (app.config):
<configuration>
<system.serviceModel>
<client>
<endpoint name="DataServiceEndpoint"
address="net.tcp://localhost:8080/DataService"
binding="netTcpBinding"
contract="Common.IDataService" />
</client>
</system.serviceModel>
</configuration>
七、安全性配置
为了增强系统安全性,可以配置 WCF 服务使用身份验证和加密:
// 配置安全绑定
NetTcpBinding secureBinding = new NetTcpBinding();
secureBinding.Security.Mode = SecurityMode.Transport;
secureBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
// 在服务主机中使用安全绑定
host.AddServiceEndpoint(
typeof(IDataService),
secureBinding,
"net.tcp://localhost:8080/SecureDataService");
八、性能优化建议
- 使用适当的绑定:对于局域网内通信,考虑使用 NetTcpBinding 代替 BasicHttpBinding
- 启用消息压缩:对于大数据传输,可以启用消息压缩
- 优化序列化:使用 DataContractSerializer 的高级特性优化序列化性能
- 使用连接池:配置适当的连接池参数提高性能
九、部署与运行说明
- 确保两台客户端机器都安装了.NET Framework 4.5 或更高版本
- 启动 Client1 的服务主机程序
- 确认服务已成功启动并监听指定端口
- 启动 Client2 程序,观察控制台输出结果
通过以上步骤,您可以实现一个完整的 WCF 分布式通信系统,Client2 能够通过 WCF 与 Client1 通信并获取数据。这种架构适用于各种分布式应用场景,如企业级应用集成、微服务通信等。