Service Host:網絡
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.ServiceModel; namespace Test.WCF.ServiceBus.Host.Service { [ServiceContract(Namespace = "urn:ps")] interface IProblemSolver { [OperationContract] int AddNumbers(int a, int b); } interface IProblemSolverChannel : IProblemSolver, IClientChannel { } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Test.WCF.ServiceBus.Host.Service { class ProblemSolver : IProblemSolver { public int AddNumbers(int a, int b) { return a + b; } } }
using Microsoft.ServiceBus; using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.Text; using System.Threading.Tasks; using Test.WCF.ServiceBus.Host.Service; namespace Test.WCF.ServiceBus.Host { class Program { static void Main(string[] args) { ServiceHost sh = new ServiceHost(typeof(ProblemSolver)); sh.AddServiceEndpoint( typeof(IProblemSolver), new NetTcpBinding(), "net.tcp://localhost:9358/***Relay Name***"); sh.AddServiceEndpoint( typeof(IProblemSolver), new NetTcpRelayBinding(), ServiceBusEnvironment.CreateServiceUri("sb", "***Service Bus Name***", "***Relay Name***")) .Behaviors.Add(new TransportClientEndpointBehavior { TokenProvider = TokenProvider.CreateSharedSecretTokenProvider("owner", "***Service Bus Token***") }); sh.Open(); Console.WriteLine("Press ENTER to close"); Console.ReadLine(); sh.Close(); } } }
Service Client:tcp
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.ServiceModel; namespace Test.WCF.ServiceBus.Client { [ServiceContract(Namespace = "urn:ps")] interface IProblemSolver { [OperationContract] int AddNumbers(int a, int b); } interface IProblemSolverChannel : IProblemSolver, IClientChannel { } }
using Microsoft.ServiceBus; using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.Text; using System.Threading.Tasks; namespace Test.WCF.ServiceBus.Client { class Program { public static ChannelFactory<IMediaServicesManagementServiceChannel> testCF=null; static void Main(string[] args) { Retry( () => { bool flag = false; var cf = new ChannelFactory<IMediaServicesManagementServiceChannel>( new NetTcpRelayBinding(), new EndpointAddress(ServiceBusEnvironment.CreateServiceUri("sb", "***Service Bus Name***", "***Relay Name***"))); cf.Endpoint.Behaviors.Add(new TransportClientEndpointBehavior { TokenProvider = TokenProvider.CreateSharedSecretTokenProvider("owner", "***Service Bus Token***") }); var ch1 = cf.CreateChannel(); try { Console.WriteLine(ch1.AddNumbers(3, 4)); flag = true; } catch { ch1.Abort(); flag = false; } finally { if (ch1 != null) { ch1.Close(); } } return flag; }, 5); Console.WriteLine("Press ENTER to close"); Console.ReadLine(); } public static void Retry(Func<bool> task, int times) { bool flag = false; for (int i = 0; i < times; i++ ) { flag = task(); if(flag==true) { break; } } } } }
這裏在client端加入了Retry的邏輯以用於因爲網絡不穩定或其餘緣由形成的Host Service Faulted State的情形。ide
同時要注意,WCF建立的Channel是Fault State時,在調用.Close()以前, 要先調用.Abort().post
Reference Links:spa
http://jeffbarnes.net/blog/post/2007/04/24/wcf-your-proxy-can-only-fault-once.aspx.net
http://blog.tallan.com/2009/05/06/recover-from-a-wcf-service-fault/code