WCF服务创建与使用(双工模式)_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > WCF服务创建与使用(双工模式)

WCF服务创建与使用(双工模式)

 2015/3/26 3:17:48  梦在旅途  程序员俱乐部  我要评论(0)
  • 摘要:昨天发布了《WCF服务创建与使用(请求应答模式)》,今天继续学习与强化在双工模式下WCF服务创建与使用,步骤与代码如下。第一步,定义服务契约(ServiceContract),注意ServiceContract特性上需指定回调契约//服务契约usingSystem.ServiceModel;namespaceWcfServiceLibrary1{[ServiceContract(Namespace="http://www.zuowenjun.cn"
  • 标签:创建 使用 模式 WCF 服务

昨天发布了《WCF服务创建与使用(请求应答模式)》,今天继续学习与强化在双工模式下WCF服务创建与使用,步骤与代码如下。

class="post_body_title">第一步,定义服务契约(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连接,如果在回调操作尚未执行完毕就试图关闭网络连接,将会导致回调无法正常执行
                }
            }
        }
    }
}

 

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

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

 

文章同步发表于我的个人网站:http://www.zuowenjun.cn/post/2015/03/25/133.html

上一篇: CLR基础(一) 下一篇: Stopwatch 类
发表评论
用户名: 匿名