第1步:创建接口
namespace WCF.Interface { //[ServiceContract(CallbackContract=typeof(ICallback))]//回调接口(全双工) [ServiceContract] public interface ICalculator { [OperationContract] double Add(double x, double y); } }
第2步:实现接口服务
namespace WCF.Service { [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] public class Calculator : ICalculator { #region ICalculator Members public double Add(double x, double y) { double result = x + y; #region 全双工回调 //ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>(); //callback.DisplayResult(x, y, result); #endregion return result; } #endregion } }
第3步:建立WinForm服务端
#region 通过代码直接定义和开启服务 /// <summary> /// 通过代码直接定义和开启服务(在启动之前必须把相应的配置文件注释或删除) /// </summary> private void HostCalculatorServiceViaCode() { try { Uri httpBaseAddress = new Uri("http://localhost:8888/Calculator");//1、基于http Uri tcpBaseAddress = new Uri("net.tcp://localhost:9999/Calculator");//2、基于tcp calculatorSerivceHost = new ServiceHost(typeof(Calculator), httpBaseAddress, tcpBaseAddress); BasicHttpBinding httpBinding = new BasicHttpBinding(); NetTcpBinding tcpBinding = new NetTcpBinding(); Type type1 = typeof(ICalculator); calculatorSerivceHost.AddServiceEndpoint(type1, httpBinding, ""); calculatorSerivceHost.AddServiceEndpoint(type1, tcpBinding, ""); ServiceMetadataBehavior behavior = calculatorSerivceHost.Description.Behaviors.Find<ServiceMetadataBehavior>(); if (behavior == null) { behavior = new ServiceMetadataBehavior(); behavior.HttpGetEnabled = true; calculatorSerivceHost.Description.Behaviors.Add(behavior); } else { behavior.HttpGetEnabled = true; } calculatorSerivceHost.Opened += delegate { txt_info.AppendText("Calculator server has begain to listen ...使用cmd命令 netstat -aon|findstr \"9999\" 查看 ...\r\n"); }; calculatorSerivceHost.Open(); } catch (Exception ex) { MessageBox.Show("详细信息:" + ex.Message,"出错提示,请确保参数配置正确且端口不被占用!", MessageBoxButtons.OK, MessageBoxIcon.Error); } } #endregion
第4步:建立Web服务端
namespace WCF.WebServer { // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Calculator”。 /// <summary> /// wcf服务应用程序,测试时端口为 7777 并启动服务网站 /// 继承于Service.Calculator,不用写额外代码直接调用 /// </summary> public class Calculator :WCF.Service.Calculator { } }
第5步:调用WinForm和Web服务端显示结果
private void InvocateCalclatorServiceViaCode() { System.ServiceModel.Channels.Binding httpBinding = new BasicHttpBinding(); System.ServiceModel.Channels.Binding tcpBinding = new NetTcpBinding(); EndpointAddress httpAddress = new EndpointAddress("http://localhost:8888/Calculator");//WinForm基于http的通道 EndpointAddress tcpAddress = new EndpointAddress("net.tcp://localhost:9999/Calculator");//WinForm基于tcp的通道 EndpointAddress webhttpAddress = new EndpointAddress("http://localhost:7777/Calculator.svc");//Web服务 txt_info.AppendText("\r\nInvocate self-host calculator service... ..."); #region Invocate Self-host service CalculatorClient calculator_http = new CalculatorClient(httpBinding, httpAddress); CalculatorClient calculator_webhttp = new CalculatorClient(httpBinding, webhttpAddress); CalculatorClient calculator_tcp = new CalculatorClient(tcpBinding, tcpAddress); try { txt_info.AppendText("\r\nBegin to invocate calculator service via http transport... ..."); txt_info.AppendText(string.Format("\r\nx + y = {2} where x = {0} and y = {1}", 1, 2, calculator_http.Add(1, 2))); txt_info.AppendText("\r\nBegin to invocate calculator service via tcp transport... ..."); txt_info.AppendText(string.Format("\r\nx + y = {2} where x = {0} and y = {1}", 1, 2, calculator_tcp.Add(1, 2))); txt_info.AppendText("\r\nBegin to invocate calculator service via webhttp transport... ..."); txt_info.AppendText(string.Format("\r\nx + y = {2} where x = {0} and y = {1}", 1, 2, calculator_webhttp.Add(1, 2))); } catch (Exception ex) { txt_info.AppendText(Environment.NewLine + ex.Message); } finally { calculator_http.Close(); calculator_tcp.Close(); } #endregion #region Invocate IIS-host service //txt_info.AppendText("\r\nInvocate IIS-host calculator service... ..."); //EndpointAddress httpAddress_iisHost = new EndpointAddress("http://localhost/wcfservice/CalculatorService.svc"); //using (CalculatorClient calculator = new CalculatorClient(httpBinding, httpAddress_iisHost)) //{ // try // { // txt_info.AppendText("\r\nBegin to invocate calculator service via http transport... ..."); // txt_info.AppendText(string.Format("\r\nx + y = {2} where x = {0} and y = {1}", 1, 2, calculator.Add(1, 2))); // } // catch (Exception ex) // { // txt_info.AppendText("\r\n"+ex.Message); // } //} #endregion }
运行效果:
如果没有运行web服务,那么web调用将出错:
测试源码:WCF服务器与客户端使用示例文件v0.2(包含全双工模式和调用web中的wcf服务).zip