WCF的执行过程
既然是实现互通信。那么肯定会有概念意义上的服务端Server 和概念意义上的客户端 Client,在这里,我所说明的都是概念意义上的,单独强调此,是因为,基于WCF的通信没有物理上的划分,但是概念上肯定有边界。原因:
1 WCF可以host(承载)在 WAS 基于Web的方式激活,也可以承载在Winform程序, Windows服务(本质就是无窗口的窗体程序),WPF程序 , 控制台程序(自承载),传统意义上 的CS架构。物理界限分明,服务端就是服务端,客户端调用发送请求到服务端。WCF这种不强制承载环境,多通信协议的三炮,彻底打乱了保守的三观。
以下是一个控制台承载的服务............
class Program
{
public static void Main()
{
ServiceHost host = new ServiceHost(typeof(MyCalculator));
host.Open();
//Can do blocking calls:
Console.WriteLine("Press ENTER to shut down service.");
Console.ReadLine();
host.Close();
}
}
配置文件:
无语了 ,太长了,一会儿在下面自己下载去.............
(下载地址:http://pan.baidu.com/s/1ntn3erB)
可见 ,这厮没有物理意义上的界限,同样,你也可以讲服务承载在你的客户端程序Winform中,当程序启动的时候,启动服务,然后就可以在程序间进行服务数据的传播。
好,说了一大堆废话,我们看看,这东西的执行过程吧。计算机世界中的东西都是按照流程走的,即使多线程并发 多进程,在CPU的世界永远都要排队执行,只不过丫执行太快,给人的幻觉是同时进行。。。。。。。
(看下面的时候:大家必须着重理解 通道通信,拦截分发,终结点的概念)
资料:http://www.cnblogs.com/millen/archive/2009/06/19/1506589.html
http://kb.cnblogs.com/page/109570/
WCF体系架构是基于一种拦截机制来实现的,负责传递和拦截消息的组件为通道,在客户端发出对服务端服务的调用时,首先会通过一个服务代理对象,将调用方提供的对象序列化到消息中,然后该消息则通过通道进行传递。通道不只是包括一个,而是多个通道对消息进行处理,包括传输、消息编码、管理会话、传播事务等,但最底层的通道总是传输通道。这些通道的构成形成了一个通道堆栈。由于对象已经被序列化,因而此时通道传递的消息可以跨进程或机器进行传递,利用传输通道传递到服务端。服务端的构成与客户端基本相似,仍然是通过通道栈中最底层的传输通道接收消息,然后解析消息编码,并一层层地往上传输。在服务端的通道栈之上,则是一个分发器(Dispatcher,或者说是调度器),它会首先对消息进行检查,然后选择一个客户端要调用的操作。在这个过程中,消息会被反序列化。
以下是执行过程的代码:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 |
namespace wcfflow
{ using System; using System.ServiceModel; using System.ServiceModel.Dispatcher; using System.Reflection; using System.ServiceModel.Channels; using System.Threading; using System.Globalization; using System.Text; using System.ServiceModel.Description; using System.Linq; [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property)] public class CommentAttribute : Attribute { public string Message { get; set; } public CommentAttribute(string message) { this.Message = message; } } class MyDispatchMessageInspector : IDispatchMessageInspector { public MyDispatchMessageInspector() { } [Comment("在已接收入站消息后将消息调度到应发送到的操作之前调用")] public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return null; } [Comment("在操作已返回后发送回复消息之前调用")] public void BeforeSendReply(ref Message reply, object correlationState) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); } } class MyDispatchMessageFormatter : IDispatchMessageFormatter { IDispatchMessageFormatter inner; public MyDispatchMessageFormatter(IDispatchMessageFormatter inner) { this.inner = inner; } [Comment("将消息反序列化为参数数组")] public void DeserializeRequest(Message message, object[] parameters) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); this.inner.DeserializeRequest(message, parameters); } [Comment("从指定的消息版本、参数数组和返回值序列化答复消息")] public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return this.inner.SerializeReply(messageVersion, parameters, result); } } class MyClientMessageInspector : IClientMessageInspector { public MyClientMessageInspector() { } [Comment("在收到回复消息之后将它传递回客户端应用程序之前,启用消息的检查或修改")] public void AfterReceiveReply(ref Message reply, object correlationState) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Yellow, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); } [Comment("在将请求消息发送到服务之前,启用消息的检查或修改")] public object BeforeSendRequest(ref Message request, IClientChannel channel) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Yellow, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return null; } } class MyClientMessageFormatter : IClientMessageFormatter { IClientMessageFormatter inner; public MyClientMessageFormatter(IClientMessageFormatter inner) { this.inner = inner; } [Comment("将消息转换为将传回给调用操作的返回值和 out 参数")] public object DeserializeReply(Message message, object[] parameters) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Yellow, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return this.inner.DeserializeReply(message, parameters); } [Comment("将 Object 数组转换为出站 Message")] public Message SerializeRequest(MessageVersion messageVersion, object[] parameters) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Yellow, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return this.inner.SerializeRequest(messageVersion, parameters); } } class MyDispatchOperationSelector : IDispatchOperationSelector { [Comment("将本地操作与传入的方法相关联")] public string SelectOperation(ref Message message) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); string action = message.Headers.Action; string method = action.Substring(action.LastIndexOf('/') + 1); return method; } } class MyParameterInspector : IParameterInspector { ConsoleColor consoleColor; bool isServer; public MyParameterInspector(bool isServer) { this.isServer = isServer; this.consoleColor = isServer ? ConsoleColor.Cyan : ConsoleColor.Yellow; } [Comment("在客户端调用返回之后、服务响应发送之前调用")] public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), this.consoleColor, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); } [Comment("在发送客户端调用之前、服务响应返回之后调用")] public object BeforeCall(string operationName, object[] inputs) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), this.consoleColor, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return null; } } class MyCallContextInitializer : ICallContextInitializer { [Comment("实现它来参与清理调用该操作的线程")] public void AfterInvoke(object correlationState) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); } [Comment("实现它来参与初始化操作线程")] public object BeforeInvoke(InstanceContext instanceContext, IClientChannel channel, Message message) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return null; } } class MyOperationInvoker : IOperationInvoker { IOperationInvoker inner; public MyOperationInvoker(IOperationInvoker inner) { this.inner = inner; } [Comment("返回参数对象的 System.Array")] public object[] AllocateInputs() { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return this.inner.AllocateInputs(); } [Comment("从一个实例和输入对象的集合返回一个对象和输出对象的集合")] public object Invoke(object instance, object[] inputs, out object[] outputs) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return this.inner.Invoke(instance, inputs, out outputs); } [Comment("开始异步方法")] public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return this.inner.InvokeBegin(instance, inputs, callback, state); } [Comment("结束异步方法")] public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return this.inner.InvokeEnd(instance, out outputs, result); } public bool IsSynchronous { [Comment("获取一个值,该值指定调度程序是调用 Invoke 方法还是调用 InvokeBegin 方法")] get { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return this.inner.IsSynchronous; } } } class MyInstanceProvider : IInstanceProvider { Type serviceType; public MyInstanceProvider(Type serviceType) { this.serviceType = serviceType; } [Comment("如果给出指定的 InstanceContext 对象,则返回服务对象")] public object GetInstance(InstanceContext instanceContext, Message message) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return Activator.CreateInstance(this.serviceType); } [Comment("如果给出指定的 InstanceContext 对象,则返回服务对象")] public object GetInstance(InstanceContext instanceContext) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return Activator.CreateInstance(this.serviceType); } [Comment("在 InstanceContext 对象回收服务对象时调用")] public void ReleaseInstance(InstanceContext instanceContext, object instance) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); } } class MyInstanceContextProvider : IInstanceContextProvider { IInstanceContextProvider inner; public MyInstanceContextProvider(IInstanceContextProvider inner) { this.inner = inner; } [Comment("接收新消息时调用")] public InstanceContext GetExistingInstanceContext(Message message, IContextChannel channel) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return this.inner.GetExistingInstanceContext(message, channel); } [Comment("当从 GetExistingInstanceContext 方法返回 null 引用时调用")] public void InitializeInstanceContext(InstanceContext instanceContext, Message message, IContextChannel channel) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); this.inner.InitializeInstanceContext(instanceContext, message, channel); } [Comment("当 InstanceContext 活动完成时调用,以使实施者能阻止 InstanceContext 的回收")] public bool IsIdle(InstanceContext instanceContext) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return this.inner.IsIdle(instanceContext); } [Comment("当 IsIdle 方法返回 false 时调用,以使实施者能提供回调,从而通知 InstanceContext 对象的完成时间")] public void NotifyIdle(InstanceContextIdleCallback callback, InstanceContext instanceContext) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); this.inner.NotifyIdle(callback, instanceContext); } } class MyInstanceContextInitializer : IInstanceContextInitializer { [Comment("用于修改新创建的 InstanceContext 对象")] public void Initialize(InstanceContext instanceContext, Message message) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); } } class MyChannelInitializer : IChannelInitializer { ConsoleColor consoleColor; public MyChannelInitializer(bool isServer) { this.consoleColor = isServer ? ConsoleColor.Cyan : ConsoleColor.Yellow; } [Comment("使用指定的 IClientChannel 来初始化 IChannelInitializer 类")] public void Initialize(IClientChannel channel) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), this.consoleColor, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); } } class MyClientOperationSelector : IClientOperationSelector { public bool AreParametersRequiredForSelection { [Comment("获取一个值,指示是否需要参数来确定选择")] get { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Yellow, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return false; } } [Comment("返回选择的操作")] public string SelectOperation(MethodBase method, object[] parameters) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Yellow, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return method.Name; } } class MyInteractiveChannelInitializer : IInteractiveChannelInitializer { [Comment("要开始使用用户接口获取凭据信息的异步调用")] public IAsyncResult BeginDisplayInitializationUI(IClientChannel channel, AsyncCallback callback, object state) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Yellow, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); Action act = new Action(this.DoNothing); return act.BeginInvoke(callback, state); } [Comment("当 BeginDisplayInitializationUI 已完成时调用")] public void EndDisplayInitializationUI(IAsyncResult result) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Yellow, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); } private void DoNothing() { } } class MyErrorHandler : IErrorHandler { [Comment("启用错误相关处理并返回一个值,该值指示调度程序在某些情况下是否中止会话和实例上下文")] public bool HandleError(Exception error) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); return error is ArgumentException; } [Comment("启用创建从服务方法过程中的异常返回的自定义 FaultException(TDetail)")] public void ProvideFault(Exception error, MessageVersion version, ref Message fault) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Cyan, "{0}.{1}", this.GetType().GetInterfaces().FirstOrDefault().FullName, ReflectionUtil.GetMethodSignature(MethodBase.GetCurrentMethod())); MessageFault messageFault = MessageFault.CreateFault(new FaultCode("FaultCode"), new FaultReason(error.Message)); fault = Message.CreateMessage(version, messageFault, "FaultAction"); } } class MyBehavior : IOperationBehavior, IContractBehavior,IEndpointBehavior,IServiceBehavior { public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { clientOperation.Formatter = new MyClientMessageFormatter(clientOperation.Formatter); clientOperation.ParameterInspectors.Add(new MyParameterInspector(false)); } public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) { dispatchOperation.CallContextInitializers.Add(new MyCallContextInitializer()); dispatchOperation.Formatter = new MyDispatchMessageFormatter(dispatchOperation.Formatter); dispatchOperation.Invoker = new MyOperationInvoker(dispatchOperation.Invoker); dispatchOperation.ParameterInspectors.Add(new MyParameterInspector(true)); } public void Validate(OperationDescription operationDescription) { } public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime) { clientRuntime.ChannelInitializers.Add(new MyChannelInitializer(false)); clientRuntime.InteractiveChannelInitializers.Add(new MyInteractiveChannelInitializer()); clientRuntime.MessageInspectors.Add(new MyClientMessageInspector()); clientRuntime.OperationSelector = new MyClientOperationSelector(); } public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) { dispatchRuntime.ChannelDispatcher.ChannelInitializers.Add(new MyChannelInitializer(true)); dispatchRuntime.ChannelDispatcher.ErrorHandlers.Add(new MyErrorHandler()); dispatchRuntime.InstanceContextInitializers.Add(new MyInstanceContextInitializer()); dispatchRuntime.InstanceContextProvider = new MyInstanceContextProvider(dispatchRuntime.InstanceContextProvider); dispatchRuntime.InstanceProvider = new MyInstanceProvider(dispatchRuntime.ChannelDispatcher.Host.Description.ServiceType); dispatchRuntime.MessageInspectors.Add(new MyDispatchMessageInspector()); dispatchRuntime.OperationSelector = new MyDispatchOperationSelector(); } public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint) { } public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { throw new NotImplementedException(); } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { throw new NotImplementedException(); } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { throw new NotImplementedException(); } public void Validate(ServiceEndpoint endpoint) { throw new NotImplementedException(); } public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { throw new NotImplementedException(); } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { throw new NotImplementedException(); } public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { throw new NotImplementedException(); } } static class ColorConsole { static object syncRoot = new object(); public static void WriteLine(MethodBase method, ConsoleColor color, string text, params object[] args) { var message = method.GetCustomAttributes(typeof(CommentAttribute), true).OfType<CommentAttribute>().FirstOrDefault(); if (args != null && args.Length > 0) { text = string.Format(CultureInfo.InvariantCulture, text, args); } lock (syncRoot) { Console.ForegroundColor = color; if (message == null) Console.WriteLine("[{0}] 执行方法: {1}", DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture), text); else Console.WriteLine("[{0}] //{1} 方法定义: {2}", DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture),message.Message, text); Console.ResetColor(); } Thread.Sleep(50); } public static void WriteLine(string text, params object[] args) { Console.WriteLine(text, args); } public static void WriteLine(object obj) { Console.WriteLine(obj); } } static class ReflectionUtil { public static string GetMethodSignature(MethodBase method) { StringBuilder sb = new StringBuilder(); sb.Append(method.Name); sb.Append("("); ParameterInfo[] parameters = method.GetParameters(); for (int i = 0; i < parameters.Length; i++) { if (i > 0) sb.Append(", "); sb.Append(parameters[i].ParameterType.Name); } sb.Append(")"); return sb.ToString(); } } [ServiceContract] public interface ITest { [OperationContract] int Add(int x, int y); [OperationContract(IsOneWay = true)] void Process(string text); } [ServiceBehavior(IncludeExceptionDetailInFaults = true)] public class Service : ITest { public int Add(int x, int y) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Green, "执行服务方法 '{0}'", MethodBase.GetCurrentMethod().Name); if (x == 0 && y == 0) { throw new ArgumentException("出现一个异常,这是异常消息"); } else { return x + y; } } public void Process(string text) { ColorConsole.WriteLine(MethodBase.GetCurrentMethod(), ConsoleColor.Green, "执行服务方法 '{0}'", MethodBase.GetCurrentMethod().Name); } } class Program { static void Main(string[] args) { string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; //配置一个服务主机 using (ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress))) { //为主机添加一个服务终结点 ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), ""); //为服务终结点添加自定义服务行为 endpoint.Contract.Behaviors.Add(new MyBehavior()); foreach (OperationDescription operation in endpoint.Contract.Operations) { operation.Behaviors.Add(new MyBehavior()); } host.Open(); ColorConsole.WriteLine("打开服务"); using (ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress))) { factory.Endpoint.Contract.Behaviors.Add(new MyBehavior()); foreach (OperationDescription operation in factory.Endpoint.Contract.Operations) { operation.Behaviors.Add(new MyBehavior()); } ITest proxy = factory.CreateChannel(); ColorConsole.WriteLine("即将调用服务"); // ColorConsole.WriteLine(proxy.Add(3, 4)); // ColorConsole.WriteLine("服务调用完成,再次调用服务,这次服务执行过程中会产生异常"); try { ColorConsole.WriteLine(proxy.Add(0, 0)); } catch (Exception e) { ColorConsole.WriteLine("{0}: {1}", e.GetType().Name, e.Message); } //ColorConsole.WriteLine("现在开始调用单向的服务"); //proxy.Process("hello"); ((IClientChannel)proxy).Close(); } } ColorConsole.WriteLine("完成"); } } } |