(2)WCF客户端调用
一、visual studion引用生成代理
引入服务端发布元数据的地址(并不是服务的地址)
用服务端是控制台程序
例子1
服务端的配置
<system.serviceModel> <services> <service name="WcfServiceLibrary6.Service1" behaviorConfiguration="HelloServiceBehavior"> <!--host这段可以测试时启动wcf测试客户端,运行后除了弹出测试客户端,也可以在浏览器中用此address访问--> <host> <baseAddresses> <add baseAddress = "http://localhost:8733/" /> </baseAddresses> </host> <endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary6.IService1" /> </service> </services> <!--元数据--> <behaviors> <serviceBehaviors > <behavior name="HelloServiceBehavior"> <serviceMetadata httpGetEnabled="True"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
用右键添加服务引用的方式
最后在客户端配置文件会自动添加xml
<system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IService1" /> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost:8733/" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" /> </client> </system.serviceModel>
例子2
把例子1的服务端终结点添加一个address属性
<endpoint address="Service1" binding="basicHttpBinding" contract="WcfServiceLibrary6.IService1" />
客户端还是引用 http://localhost:8733/
生成xml,发现地址多出了一个Service1
例子3
把例子1的服务端终结点添加一个address属性
<endpoint address="http://localhost:22222/" binding="basicHttpBinding" contract="WcfServiceLibrary6.IService1" />
客户端引用依然是 http://localhost:8733/
生成xml,生成的地址变成了终结点的地址
<system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IService1" /> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost:22222/" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" /> </client> </system.serviceModel>
例4
使用tcp部署服务端
<system.serviceModel> <services> <service name="WcfServiceLibrary6.Service1" behaviorConfiguration="HelloServiceBehavior"> <!--host这段可以测试时启动wcf测试客户端,运行后除了弹出测试客户端,也可以在浏览器中用此address访问--> <host> <baseAddresses> <add baseAddress = "net.tcp://localhost:8733/" /> </baseAddresses> </host> <endpoint address="net.tcp://localhost:22222/" binding="netTcpBinding" contract="WcfServiceLibrary6.IService1" /> <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> </service> </services> <!--元数据--> <behaviors> <serviceBehaviors > <behavior name="HelloServiceBehavior"> <serviceMetadata /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
客户端引用
生成
<system.serviceModel> <bindings> <netTcpBinding> <binding name="NetTcpBinding_IService1" /> </netTcpBinding> </bindings> <client> <endpoint address="net.tcp://localhost:22222/" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IService1" contract="ServiceReference1.IService1" name="NetTcpBinding_IService1"> <identity> <userPrincipalName value="XTZ-01805141702\Administrator" /> </identity> </endpoint> </client> </system.serviceModel>
二、使用SvcUtil生成代理
假设有服务端配置
契约
[ServiceContract] public interface IService1 { [OperationContract] string GetData(int value); }
public class Service1 : IService1 { public string GetData(int value) { return string.Format("You entered: {0}", value); } }
服务端控制台
static void Main(string[] args) { Uri httpBaseAddress = new Uri("http://localhost:9001/"); Uri tcpBaseAddress = new Uri("net.tcp://localhost:9002/"); ServiceHost host = new ServiceHost(typeof(Service1), httpBaseAddress, tcpBaseAddress); ////启动行为 ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>(); if (smb == null) { smb = new ServiceMetadataBehavior(); } smb.HttpGetEnabled = true; host.Description.Behaviors.Add(smb); host.Open(); Console.WriteLine("Service已经启动,按任意键终止服务!"); Console.Read(); host.Close(); }
使用工具生成代理
在C盘 SvcUtil.exe 能搜索到此工具
把它拷贝到一个单独的文件夹,用cmd指令进入该目录。这里我考到了h盘的根目录下
SvcUtil http://localhost:9001 /out:proxy.cs
生成 二个文件 output.config和proxy.cs
output.config
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IService1" /> </basicHttpBinding> <netTcpBinding> <binding name="NetTcpBinding_IService1" /> </netTcpBinding> </bindings> <client> <endpoint address="http://localhost:9001/" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="IService1" name="BasicHttpBinding_IService1" /> <endpoint address="net.tcp://localhost:9002/" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IService1" contract="IService1" name="NetTcpBinding_IService1"> <identity> <userPrincipalName value="XTZ-01805141702\Administrator" /> </identity> </endpoint> </client> </system.serviceModel> </configuration>
proxy.cs
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] [System.ServiceModel.ServiceContractAttribute(ConfigurationName="IService1")] public interface IService1 { [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetData", ReplyAction="http://tempuri.org/IService1/GetDataResponse")] string GetData(int value); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetData", ReplyAction="http://tempuri.org/IService1/GetDataResponse")] System.Threading.Tasks.Task<string> GetDataAsync(int value); } [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] public interface IService1Channel : IService1, System.ServiceModel.IClientChannel { } [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] public partial class Service1Client : System.ServiceModel.ClientBase<IService1>, IService1 { public Service1Client() { } public Service1Client(string endpointConfigurationName) : base(endpointConfigurationName) { } public Service1Client(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public Service1Client(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public Service1Client(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public string GetData(int value) { return base.Channel.GetData(value); } public System.Threading.Tasks.Task<string> GetDataAsync(int value) { return base.Channel.GetDataAsync(value); } }
config文件尽量自己手写,不用自动生成的,终结要有名字。
三 编写客户端
以下客户端的服务端应用的是 “标题二”下的契约和服务
(1)使用工具代理文件编程
创建一个控制台,output.config文件的内容复制到控制台下的app.config,再把生成的代理文件复制到控制台下
Program.cs
class Program { static void Main(string[] args) { Service1Client proxy = new Service1Client("BasicHttpBinding_IService1");//传入客户端终结点名称 string str=proxy.GetData(6); proxy.Close(); Console.Write(str); Console.ReadKey(); } }
运行
(2)引用方式编程
客户端引用后的xml
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" /> </startup> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IService1" /> </basicHttpBinding> <netTcpBinding> <binding name="NetTcpBinding_IService1" /> </netTcpBinding> </bindings> <client> <endpoint address="http://localhost:9001/" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" /> <endpoint address="net.tcp://localhost:9002/" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IService1" contract="ServiceReference1.IService1" name="NetTcpBinding_IService1"> <identity> <userPrincipalName value="XTZ-01805141702\Administrator" /> </identity> </endpoint> </client> </system.serviceModel> </configuration>
class Program { static void Main(string[] args) { var client = new ServiceReference1.Service1Client("BasicHttpBinding_IService1");//使用http通讯 //var client = new ServiceReference1.Service1Client("NetTcpBinding_IService1");//使用tcp通讯 string str = client.GetData(6); client.Close(); Console.Write(str); Console.ReadKey(); } }