• Wcf服务的创建和使用


    引用网址:https://www.likecs.com/show-305333773.html

    第一步,定义服务契约(Service Contract),注意ServiceContract特性上需指定回调契约

    //服务契约
    using System.ServiceModel;
    
    namespace WcfServiceLibrary1
    {
        [ServiceContract(Namespace = "http://www.zuowenjun.cn",
         CallbackContract = typeof(ICallback))]
        public interface IHello
        {
            [OperationContract(IsOneWay = true)]
            void SetName(string name);
        }
    }
    
    //回调契约(由于回调契约本质也是一个服务契约,所以定义方式和一般意义上的服务契约基本一样。
    //有一点不同的是,由于定义服务契约时候已经通过[ServiceContract(CallbackContract=typeof(ICallback))]指明ICallback是一个服务契约了,所以ICallback不再需要添加ServiceContractAttribute特性)
    using System.ServiceModel;
    
    namespace WcfServiceLibrary1
    {
        public interface ICallback
        {
            [OperationContract(IsOneWay = true)]
            void ShowHello(string name);
        }
    }
    
    

    第二步,实现服务契约,这里通过OperationContext.Current.GetCallbackChannel()获取回调契约

    using System.ServiceModel;
    
    namespace WcfServiceLibrary1
    {
        [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
        public class HelloService:IHello
        {
            public void SetName(string name)
            {
                ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
                callback.ShowHello(name);
            }
        }
    }
    
    
    

    注意:ConcurrencyMode = ConcurrencyMode.Reentrant是设置并发模式,Reentrant与Multiple均可适用于多并发,默认是Single

    第三步,创建服务寄宿程序,方法很多,我这里采取常用的配置方法

    1.CONFIG文件配置部份:

    (注: 1.在WCF预定义绑定类型中,WSDualHttpBinding和NetTcpBinding均提供了对双工通信的支持,但是两者在对双工通信的实现机制上却有本质的区别。WSDualHttpBinding是基于HTTP传输协议的;而HTTP协议本身是基于请求-回复的传输协议,基于HTTP的通道本质上都是单向的。WSDualHttpBinding实际上创建了两个通道,一个用于客户端向服务端的通信,而另一个则用于服务端到客户端的通信,从而间接地提供了双工通信的实现。而NetTcpBinding完全基于支持双工通信的TCP协议。
    2.若绑定类型采用NetTcpBinding,则地址应变更为:net.tcp://127.0.0.1:10800/HelloService,且不能有behaviorConfiguration配置)

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <system.serviceModel>
        <services>
          </service>
          <service name="WcfServiceLibrary1.HelloService">
            <endpoint address="http://127.0.0.1:10800/HelloService" binding="wsDualHttpBinding" contract="WcfServiceLibrary1.IHello"></endpoint>
          </service>
        </services>
      </system.serviceModel>
    </configuration>
    
    

    2.代码部份:

    using System;
    using WcfServiceLibrary1;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    
    
    namespace ConsoleApplicationHost
    {
        class Program
        {
            static void Main(string[] args)
            {
                BuildHelloServiceHostByConfig();
            }
    
            static void BuildHelloServiceHostByConfig()
            {
                using (ServiceHost host = new ServiceHost(typeof(HelloService)))
                {
                    host.Opened += (s, e) => { Console.WriteLine("HelloService已经启动,按按回车键终止服务!"); };
                    host.Open();
                    Console.ReadLine();
                }
            }
        }
    }
    
    

    第四步,客户端程序调用WCF服务

    注:在客户端程序中首先需要创建或引用WCF服务类库,然后创建实现回调契约的类

    实现回调契约:

    using System;
    using WcfServiceLibrary1;
    
    namespace ConsoleApplicationClient
    {
        public class HelloCallBack:ICallback
        {
            public void ShowHello(string name)
            {
                Console.WriteLine("Hello! {0}.欢迎光临IT文俊社区网,地址:www.zuowenjun.cn",name);
            }
        }
    }
    
    
    

    1.CONFIG文件配置部份:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <system.serviceModel>
            <bindings>
              <wsDualHttpBinding>
                <binding name="HelloServiceBinding" clientBaseAddress="http://127.0.0.1:10801/HelloServiceCallback"></binding>
              </wsDualHttpBinding>
            </bindings>
            <client>
              <endpoint name="HelloService" address="http://127.0.0.1:10800/HelloService" binding="wsDualHttpBinding" contract="WcfServiceLibrary1.IHello">
              </endpoint>
            </client>
        </system.serviceModel>
    </configuration>
    
    

    2.代码部份:

    using System;
    using System.ServiceModel;
    using WcfServiceLibrary1;
    
    namespace ConsoleApplicationClient
    {
        class Program
        {
            static void Main(string[] args)
            {
                CallHelloService();
                Console.WriteLine("按任意键结束。");
                Console.Read();
            }
    
            static void CallHelloService()
            {
                Console.Write("请输入您的网名:");
                string input = Console.ReadLine();
                InstanceContext instanceContext = new InstanceContext(new HelloCallBack());
                using (DuplexChannelFactory<IHello> channel = new DuplexChannelFactory<IHello>(instanceContext, "HelloService"))
                {
                    IHello proxy = channel.CreateChannel();
                    using (proxy as IDisposable)
                    {
                        proxy.SetName(input);
                        Console.ReadLine();//注意这句需保留,目的是为了阻止调用proxy的Dispose方法,因为该方法将会试图关闭底层的TCP连接。由于服务端的回调操作也会使用该TCP连接,如果在回调操作尚未执行完毕就试图关闭网络连接,将会导致回调无法正常执行
                    }
                }
            }
        }
    }
    
    

    这里特别说明一下,建议在定义服务方法时,若没有返回值,建议为方法添加IsOneWay=True特性,可以使客户端不用等待请求回复,虽然设置ConcurrencyMode = ConcurrencyMode.Reentrant,但若采用WINFORM客户端使用,则会出现TIMEOUT错误,具体分析与解决方法,详见:我的WCF之旅(6):在Winform Application中调用Duplex Service出现TimeoutException的原因和解决方案

    说明:发表这篇文章参考了如下作者的文章:

    我的WCF之旅(3):在WCF中实现双工通信

  • 相关阅读:
    SmartSql = Dapper + MyBatis + Cache(Memory | Redis) + ZooKeeper + R/W Splitting + ......
    SmartSql For Asp.Net Core 最佳实践
    如何通过本地化事件正确实现微服务内部强一致性,事件总线跨微服务间最终一致性
    Netty入门搭建
    IO同步阻塞与同步非阻塞
    NIO的缓冲区、通道、选择器关系理解
    SpringBoot整合ActiveMQ
    ActiveMQ的介绍及使用
    nginx入门(一)
    垃圾回收器及tomcat调优
  • 原文地址:https://www.cnblogs.com/bruce1992/p/16596131.html
Copyright © 2020-2023  润新知