none
请问服务端如何在当前连接调用客户端方法? RRS feed

  • 问题

  • 大家好,有个问题困扰好几天,故发帖求助,望大神不吝赐教。

    客户端调用服务端的Empty方法时,服务端要在此方法里回调客户端的GetRPCMethods方法
    public void Empty()
    {
        cpeService client = new cpeService();
        string[] methodlist = new string[9];
        methodlist = client.GetRPCMethods();
        ......
    }

    cpeService类是根据wsdl生成的代理类:
    public partial class cpeService
    {
        ......
        public cpeService()
        {
            this.Url = "http://192.168.20.160:9999/cpe";    //引号中的内容是从wsdl文件里来的,即客户端地址
        }
        ......
        [System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="urn:dslforum-org:cwmp-1-0", ResponseNamespace="urn:dslforum-org:cwmp-1-0", Use=System.Web.Services.Description.SoapBindingUse.Literal)]
        [return: System.Xml.Serialization.XmlArrayAttribute("MethodList")]
        [return: System.Xml.Serialization.XmlArrayItemAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string[] GetRPCMethods() {
            object[] results = this.Invoke("GetRPCMethods", new object[0]);
            return ((string[])(results[0]));
        }
        ......
    }

    现在的问题是,抓包看客户端调用Empty方法时,服务端会对客户端发起一个新连接调用GetRPCMethods,而不是用现有的连接。我想主要是因为cpeService client = new cpeService();这一句吧,现在对C#和WCF不了解,不知道该看哪部分内容。亲们可否提供个思路?
    不用WCF回调是因为看书上回调的绑定WSDualHttpBinding不支持https。
    2014年2月14日 9:34

答案

  • 使用 customBinding,绑定元素中依次添加 httpsTransport 和 compositeDuplex 元素。

    compositeDuplex 元素:http://msdn.microsoft.com/zh-cn/library/ms731351(v=vs.110).aspx

    PS:我个人建议使用 WCF 回调机制时,最好不要使用无状态的协议。如果你必须使用无状态协议,那么不使用回调,而是显式调用客户端服务,将是一个更好的方式。因为这两种方式,都会建立从服务器到客户端的连接,也就是你提到的:服务端会对客户端发起一个新连接调用 GetRPCMethods。

    2014年2月17日 1:37

全部回复

  • 我想主要是因为cpeService client = new cpeService();这一句吧,现在对C#和WCF不了解,不知道该看哪部分内容。亲们可否提供个思路?
    不用WCF回调是因为看书上回调的绑定WSDualHttpBinding不支持https。

    你好!

    根据你的描述,我认为你想实现WCF回调客户端的方法。

    Http 协议是无状态无连接的,所以它不能实现WCF的回调功能。 而WCF支持“WSDualHttpBinding” 绑定来实现回调操作。

    TCP和IPC协议是双工通信的,所以所有的相关的协议是可以用来回调操作。

    对于WCF回调客户端方法,我们可以看作客户端作为service,服务端作为client。如果要实现WCF回调,我们可以这样声明服务契约。

     public interface IMyContractCallback
        {
            [OperationContract]
            void OnCallback();
        }
        [ServiceContract(CallbackContract = typeof(IMyContractCallback))]
        public interface IMyContract
        {
            [OperationContract()]
            void MyMethod();
        }
    

    利用CallBackContract来声明回调服务。在客户端我们可以这样调用服务:

    IMyContractCallback callback=new MyCallback();
    InstanceContext cntx=new InstanceContext(callback);
    
    MyServiceClient proxy = new MyServiceClient(cntx);
    proxy.MyMethod();   
    

    在服务端我们可以这样启用回调方法:

    IMyContractCallback callbackInstance=OperationContext.Current.GetCallbackChannel();
    callbackInstance.OnCallback();
    
    

    这里有一个实现WCF回调功能的完整例子,请参照该例子完成WCF CallBack.

    http://idunno.org/archive/2008/05/29/wcf-callbacks-a-beginners-guide.aspx

    希望对你有帮助,谢谢!

    2014年2月16日 9:45
    版主
  • 您好,感谢您的回复。但是这个过程协议要求支持https,据暂时所知,WSDualHttpBinding不支持https,所以不能用来解决此问题。您是否有更好的方法?
    2014年2月17日 0:41
  • 使用 customBinding,绑定元素中依次添加 httpsTransport 和 compositeDuplex 元素。

    compositeDuplex 元素:http://msdn.microsoft.com/zh-cn/library/ms731351(v=vs.110).aspx

    PS:我个人建议使用 WCF 回调机制时,最好不要使用无状态的协议。如果你必须使用无状态协议,那么不使用回调,而是显式调用客户端服务,将是一个更好的方式。因为这两种方式,都会建立从服务器到客户端的连接,也就是你提到的:服务端会对客户端发起一个新连接调用 GetRPCMethods。

    2014年2月17日 1:37