跟着Artech学习WCF(1)
折腾了老半天双向通信,不是端口绑定不上 就是创建代理失败要摸是 代理没有及时关闭Artech的代码看了半天无论是照抄还是改良都是不行,无奈到处看看test最后终于解决了
绑定协议现在只试了http还没有事tcp的
项目结构图如下
目前感觉客户端的调用部分代码很多不 来自博客园地址忘了呵呵
代码如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace Contracts { [ServiceContract(Namespace="http://www.artech.com/",CallbackContract=typeof(ICallback))] public interface ICalculator { [OperationContract(IsOneWay = true)] void add(double x, double y); [OperationContract(IsOneWay = true)] void Subtract(double x, double y); } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace Contracts { public interface ICallback { [OperationContract(IsOneWay=true)] void DisplayResult(double x, double y, double result); } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Contracts; using System.ServiceModel; namespace Services { public class CalculatorService:ICalculator { void ICalculator.add(double x, double y) { double result = x + y; ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>(); callback.DisplayResult(x, y, result); } void ICalculator.Subtract(double x, double y) { double result = x - y; ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>(); callback.DisplayResult(x, y, result); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using Services; using Contracts; namespace Hosting { class Program { static void Main(string[] args) { using (ServiceHost host = new ServiceHost(typeof(CalculatorService))) { try { host.Opened += delegate { Console.WriteLine("CalculaorService已经启动,按任意键终止服务!"); }; host.Open(); Console.Read(); } catch (Exception ex) { } } } } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.ServiceModel; using Contracts; namespace Client { public partial class Form1 : Form, ICallback { public Form1() { InitializeComponent(); IniProxy(); } MyDataClient client = null; public void IniProxy() { client = new MyDataClient(new InstanceContext(this), "WSDualHttpBinding_ICalculator"); } void ICallback.DisplayResult(double x, double y, double result) { this.label1.Text = x.ToString() + "||"+y.ToString()+"||" + result.ToString(); } private void button1_Click(object sender, EventArgs e) { client.add(1, 2); // ServiceReference2 #region MyRegion //InstanceContext instanceContext = new InstanceContext(this); //using (DuplexChannelFactory<ICalculator> channelFactory = new DuplexChannelFactory<ICalculator>(instanceContext, "WSDualHttpBinding_ICalculator")) //{ // ICalculator proxy = channelFactory.CreateChannel(); // using (proxy as IDisposable) // { // proxy.add(1, 2); // Console.Read(); // } //} #endregion } } class MyDataClient : ClientBase<ICalculator>, ICalculator { internal MyDataClient(InstanceContext callback, string configendpoint) : base(callback, configendpoint) { } public void add(double x, double y) { this.Channel.add(x, y); } public void Subtract(double x, double y) { this.Channel.Subtract(x, y); } } //class CalculateCallback : ICallback //{ // void ICallback.DisplayResult(double x, double y, double result) // { // } //} }
服务器端的配置
<system.serviceModel> <!--<behaviors> <serviceBehaviors> <behavior name="metadataBehavior"> <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:9999/calculatorservice/metadata"/> </behavior> </serviceBehaviors> </behaviors>--> <!--<services> <service name="Services.CalculatorService"> <endpoint address="http://localhost:9999/calculatorservice" binding="" contract="Contracts.ICalculator" /> </service> </services>--> <behaviors> <serviceBehaviors> <behavior name="metadataBehavior"> <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:9999/CalculatorService/metadata"/> </behavior> </serviceBehaviors> </behaviors> <services> <service name="Services.CalculatorService" behaviorConfiguration="metadataBehavior"> <endpoint address="http://localhost:9999/CalculatorService" binding="wsDualHttpBinding" contract="Contracts.ICalculator" /> </service> </services> </system.serviceModel>
客户端的配置
<system.serviceModel> <bindings> <wsDualHttpBinding> <binding name="WSDualHttpBinding_ICalculator" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" /> <security mode="Message"> <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" /> </security> </binding> </wsDualHttpBinding> </bindings> <client> <endpoint address="http://localhost:9999/CalculatorService" binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_ICalculator" contract="Contracts.ICalculator" name="WSDualHttpBinding_ICalculator"> <identity> <userPrincipalName value="zhangc-PC\Administrator" /> </identity> </endpoint> </client> </system.serviceModel>
test