来自代码项目的WCF聊天应用程序 - 理解

时间:2017-10-14 05:21:33

标签: c# wcf asynchronous proxy

我尝试从codeproject中了解一个名为WCF / WPF聊天应用程序的项目Link

服务器端没什么大不了的,但我对代理的实现有问题:

获取代理类有两种方法 1.使用svcutil.exe 2.使用Service Refernce(后台也使用svcutil)

项目中的原始代理类:

using Common;

/// <summary>
/// This class was auto generated by the svcutil.exe utility. 
/// The www.codeprject.com article will explain how this class
/// was generated, for those readers that just need to know. 
/// Basically, anyone like me.
/// </summary>
#region IChat interface
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(CallbackContract = typeof(IChatCallback), SessionMode = System.ServiceModel.SessionMode.Required)]
public interface IChat
{

    [System.ServiceModel.OperationContractAttribute(AsyncPattern = true, Action = "http://tempuri.org/IChat/Join", ReplyAction = "http://tempuri.org/IChat/JoinResponse")]
    System.IAsyncResult BeginJoin(Person name, System.AsyncCallback callback, object asyncState);

    Person[] EndJoin(System.IAsyncResult result);

    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, IsInitiating = false, Action = "http://tempuri.org/IChat/Leave")]
    void Leave();

    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, IsInitiating = false, Action = "http://tempuri.org/IChat/Say")]
    void Say(string msg);

    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, IsInitiating = false, Action = "http://tempuri.org/IChat/Whisper")]
    void Whisper(string to, string msg);
}
#endregion
#region IChatCallback interface 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface IChatCallback
{

    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://tempuri.org/IChat/Receive")]
    void Receive(Person sender, string message);

    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://tempuri.org/IChat/ReceiveWhisper")]
    void ReceiveWhisper(Person sender, string message);

    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://tempuri.org/IChat/UserEnter")]
    void UserEnter(Person person);

    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://tempuri.org/IChat/UserLeave")]
    void UserLeave(Person person);
}
#endregion
#region IChatChannel interface
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface IChatChannel : IChat, System.ServiceModel.IClientChannel
{
}
#endregion
#region ChatProxy class
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class ChatProxy : System.ServiceModel.DuplexClientBase<IChat>, IChat
{

    public ChatProxy(System.ServiceModel.InstanceContext callbackInstance)
        :
            base(callbackInstance)
    {
    }

    public ChatProxy(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName)
        :
            base(callbackInstance, endpointConfigurationName)
    {
    }

    public ChatProxy(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, string remoteAddress)
        :
            base(callbackInstance, endpointConfigurationName, remoteAddress)
    {
    }

    public ChatProxy(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress)
        :
            base(callbackInstance, endpointConfigurationName, remoteAddress)
    {
    }

    public ChatProxy(System.ServiceModel.InstanceContext callbackInstance, System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress)
        :
            base(callbackInstance, binding, remoteAddress)
    {
    }

    public System.IAsyncResult BeginJoin(Person name, System.AsyncCallback callback, object asyncState)
    {
        return base.Channel.BeginJoin(name, callback, asyncState);
    }

    public Person[] EndJoin(System.IAsyncResult result)
    {
        return base.Channel.EndJoin(result);
    }

    public void Leave()
    {
        base.Channel.Leave();
    }

    public void Say(string msg)
    {
        base.Channel.Say(msg);
    }

    public void Whisper(string to, string msg)
    {
        base.Channel.Whisper(to, msg);
    }
}
#endregion

由我生成的代理类:

使用--svcutil * .wsdl * .xsd / language:C#/out:ChatService_without_a.cs /config:app_without_a.config

//------------------------------------------------------------------------------
// <auto-generated>
//     Dieser Code wurde von einem Tool generiert.
//     Laufzeitversion:4.0.30319.42000
//
//     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
//     der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Common
{
    using System.Runtime.Serialization;


    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute(Name="Person", Namespace="http://schemas.datacontract.org/2004/07/Common")]
    public partial class Person : object, System.Runtime.Serialization.IExtensibleDataObject
    {

        private System.Runtime.Serialization.ExtensionDataObject extensionDataField;

        private string ImageURLField;

        private string NameField;

        public System.Runtime.Serialization.ExtensionDataObject ExtensionData
        {
            get
            {
                return this.extensionDataField;
            }
            set
            {
                this.extensionDataField = value;
            }
        }

        [System.Runtime.Serialization.DataMemberAttribute()]
        public string ImageURL
        {
            get
            {
                return this.ImageURLField;
            }
            set
            {
                this.ImageURLField = value;
            }
        }

        [System.Runtime.Serialization.DataMemberAttribute()]
        public string Name
        {
            get
            {
                return this.NameField;
            }
            set
            {
                this.NameField = value;
            }
        }
    }
}


[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="IChat", CallbackContract=typeof(IChatCallback), SessionMode=System.ServiceModel.SessionMode.Required)]
public interface IChat
{

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, IsInitiating=false, Action="http://tempuri.org/IChat/Say")]
    void Say(string msg);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, IsInitiating=false, Action="http://tempuri.org/IChat/Say")]
    System.Threading.Tasks.Task SayAsync(string msg);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, IsInitiating=false, Action="http://tempuri.org/IChat/Whisper")]
    void Whisper(string to, string msg);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, IsInitiating=false, Action="http://tempuri.org/IChat/Whisper")]
    System.Threading.Tasks.Task WhisperAsync(string to, string msg);

    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IChat/Join", ReplyAction="http://tempuri.org/IChat/JoinResponse")]
    Common.Person[] Join(Common.Person name);

    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IChat/Join", ReplyAction="http://tempuri.org/IChat/JoinResponse")]
    System.Threading.Tasks.Task<Common.Person[]> JoinAsync(Common.Person name);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, IsTerminating=true, IsInitiating=false, Action="http://tempuri.org/IChat/Leave")]
    void Leave();

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, IsTerminating=true, IsInitiating=false, Action="http://tempuri.org/IChat/Leave")]
    System.Threading.Tasks.Task LeaveAsync();
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IChatCallback
{

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://tempuri.org/IChat/Receive")]
    void Receive(Common.Person sender, string message);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://tempuri.org/IChat/ReceiveWhisper")]
    void ReceiveWhisper(Common.Person sender, string message);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://tempuri.org/IChat/UserEnter")]
    void UserEnter(Common.Person person);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://tempuri.org/IChat/UserLeave")]
    void UserLeave(Common.Person person);
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IChatChannel : IChat, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class ChatClient : System.ServiceModel.DuplexClientBase<IChat>, IChat
{

    public ChatClient(System.ServiceModel.InstanceContext callbackInstance) : 
            base(callbackInstance)
    {
    }

    public ChatClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName) : 
            base(callbackInstance, endpointConfigurationName)
    {
    }

    public ChatClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, string remoteAddress) : 
            base(callbackInstance, endpointConfigurationName, remoteAddress)
    {
    }

    public ChatClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(callbackInstance, endpointConfigurationName, remoteAddress)
    {
    }

    public ChatClient(System.ServiceModel.InstanceContext callbackInstance, System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(callbackInstance, binding, remoteAddress)
    {
    }

    public void Say(string msg)
    {
        base.Channel.Say(msg);
    }

    public System.Threading.Tasks.Task SayAsync(string msg)
    {
        return base.Channel.SayAsync(msg);
    }

    public void Whisper(string to, string msg)
    {
        base.Channel.Whisper(to, msg);
    }

    public System.Threading.Tasks.Task WhisperAsync(string to, string msg)
    {
        return base.Channel.WhisperAsync(to, msg);
    }

    public Common.Person[] Join(Common.Person name)
    {
        return base.Channel.Join(name);
    }

    public System.Threading.Tasks.Task<Common.Person[]> JoinAsync(Common.Person name)
    {
        return base.Channel.JoinAsync(name);
    }

    public void Leave()
    {
        base.Channel.Leave();
    }

    public System.Threading.Tasks.Task LeaveAsync()
    {
        return base.Channel.LeaveAsync();
    }
}

使用--svcutil * .wsdl * .xsd / a / language:C#/out:ChatService_with_a.cs /config:app_with_a.config

//------------------------------------------------------------------------------
// <auto-generated>
//     Dieser Code wurde von einem Tool generiert.
//     Laufzeitversion:4.0.30319.42000
//
//     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
//     der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Common
{
    using System.Runtime.Serialization;


    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute(Name="Person", Namespace="http://schemas.datacontract.org/2004/07/Common")]
    public partial class Person : object, System.Runtime.Serialization.IExtensibleDataObject
    {

        private System.Runtime.Serialization.ExtensionDataObject extensionDataField;

        private string ImageURLField;

        private string NameField;

        public System.Runtime.Serialization.ExtensionDataObject ExtensionData
        {
            get
            {
                return this.extensionDataField;
            }
            set
            {
                this.extensionDataField = value;
            }
        }

        [System.Runtime.Serialization.DataMemberAttribute()]
        public string ImageURL
        {
            get
            {
                return this.ImageURLField;
            }
            set
            {
                this.ImageURLField = value;
            }
        }

        [System.Runtime.Serialization.DataMemberAttribute()]
        public string Name
        {
            get
            {
                return this.NameField;
            }
            set
            {
                this.NameField = value;
            }
        }
    }
}


[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="IChat", CallbackContract=typeof(IChatCallback), SessionMode=System.ServiceModel.SessionMode.Required)]
public interface IChat
{

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, IsInitiating=false, Action="http://tempuri.org/IChat/Say")]
    void Say(string msg);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, IsInitiating=false, AsyncPattern=true, Action="http://tempuri.org/IChat/Say")]
    System.IAsyncResult BeginSay(string msg, System.AsyncCallback callback, object asyncState);

    void EndSay(System.IAsyncResult result);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, IsInitiating=false, Action="http://tempuri.org/IChat/Whisper")]
    void Whisper(string to, string msg);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, IsInitiating=false, AsyncPattern=true, Action="http://tempuri.org/IChat/Whisper")]
    System.IAsyncResult BeginWhisper(string to, string msg, System.AsyncCallback callback, object asyncState);

    void EndWhisper(System.IAsyncResult result);

    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IChat/Join", ReplyAction="http://tempuri.org/IChat/JoinResponse")]
    Common.Person[] Join(Common.Person name);

    [System.ServiceModel.OperationContractAttribute(AsyncPattern=true, Action="http://tempuri.org/IChat/Join", ReplyAction="http://tempuri.org/IChat/JoinResponse")]
    System.IAsyncResult BeginJoin(Common.Person name, System.AsyncCallback callback, object asyncState);

    Common.Person[] EndJoin(System.IAsyncResult result);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, IsTerminating=true, IsInitiating=false, Action="http://tempuri.org/IChat/Leave")]
    void Leave();

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, IsTerminating=true, IsInitiating=false, AsyncPattern=true, Action="http://tempuri.org/IChat/Leave")]
    System.IAsyncResult BeginLeave(System.AsyncCallback callback, object asyncState);

    void EndLeave(System.IAsyncResult result);
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IChatCallback
{

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://tempuri.org/IChat/Receive")]
    void Receive(Common.Person sender, string message);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, AsyncPattern=true, Action="http://tempuri.org/IChat/Receive")]
    System.IAsyncResult BeginReceive(Common.Person sender, string message, System.AsyncCallback callback, object asyncState);

    void EndReceive(System.IAsyncResult result);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://tempuri.org/IChat/ReceiveWhisper")]
    void ReceiveWhisper(Common.Person sender, string message);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, AsyncPattern=true, Action="http://tempuri.org/IChat/ReceiveWhisper")]
    System.IAsyncResult BeginReceiveWhisper(Common.Person sender, string message, System.AsyncCallback callback, object asyncState);

    void EndReceiveWhisper(System.IAsyncResult result);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://tempuri.org/IChat/UserEnter")]
    void UserEnter(Common.Person person);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, AsyncPattern=true, Action="http://tempuri.org/IChat/UserEnter")]
    System.IAsyncResult BeginUserEnter(Common.Person person, System.AsyncCallback callback, object asyncState);

    void EndUserEnter(System.IAsyncResult result);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://tempuri.org/IChat/UserLeave")]
    void UserLeave(Common.Person person);

    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, AsyncPattern=true, Action="http://tempuri.org/IChat/UserLeave")]
    System.IAsyncResult BeginUserLeave(Common.Person person, System.AsyncCallback callback, object asyncState);

    void EndUserLeave(System.IAsyncResult result);
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IChatChannel : IChat, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class ChatClient : System.ServiceModel.DuplexClientBase<IChat>, IChat
{

    public ChatClient(System.ServiceModel.InstanceContext callbackInstance) : 
            base(callbackInstance)
    {
    }

    public ChatClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName) : 
            base(callbackInstance, endpointConfigurationName)
    {
    }

    public ChatClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, string remoteAddress) : 
            base(callbackInstance, endpointConfigurationName, remoteAddress)
    {
    }

    public ChatClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(callbackInstance, endpointConfigurationName, remoteAddress)
    {
    }

    public ChatClient(System.ServiceModel.InstanceContext callbackInstance, System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(callbackInstance, binding, remoteAddress)
    {
    }

    public void Say(string msg)
    {
        base.Channel.Say(msg);
    }

    public System.IAsyncResult BeginSay(string msg, System.AsyncCallback callback, object asyncState)
    {
        return base.Channel.BeginSay(msg, callback, asyncState);
    }

    public void EndSay(System.IAsyncResult result)
    {
        base.Channel.EndSay(result);
    }

    public void Whisper(string to, string msg)
    {
        base.Channel.Whisper(to, msg);
    }

    public System.IAsyncResult BeginWhisper(string to, string msg, System.AsyncCallback callback, object asyncState)
    {
        return base.Channel.BeginWhisper(to, msg, callback, asyncState);
    }

    public void EndWhisper(System.IAsyncResult result)
    {
        base.Channel.EndWhisper(result);
    }

    public Common.Person[] Join(Common.Person name)
    {
        return base.Channel.Join(name);
    }

    public System.IAsyncResult BeginJoin(Common.Person name, System.AsyncCallback callback, object asyncState)
    {
        return base.Channel.BeginJoin(name, callback, asyncState);
    }

    public Common.Person[] EndJoin(System.IAsyncResult result)
    {
        return base.Channel.EndJoin(result);
    }

    public void Leave()
    {
        base.Channel.Leave();
    }

    public System.IAsyncResult BeginLeave(System.AsyncCallback callback, object asyncState)
    {
        return base.Channel.BeginLeave(callback, asyncState);
    }

    public void EndLeave(System.IAsyncResult result)
    {
        base.Channel.EndLeave(result);
    }
}

如果我现在将原始的ChatService Proxy类与我生成的类进行比较,我得到的问题是我生成的类都不相同。

  1. 还会生成人员类 - 好的,因为他使用相同的项目并且可以使用原始类
  2. 结构,评论.... - 好的
  3. 在IChat中他删除了一些方法! - 为什么
  4. 在IchatCallback中,他使用非asnvy方法
  5. ChatProxy / ChatClient他重命名了这个类 - 确定
  6. 在ChatProxy中,他从异步gnerated ChatClient
  7. 中删除了所有异步方法

    任何人都能解释我他做到了吗?这个理想的好处是什么?

    我还尝试了服务参考方式,我认为这是最简单的方法(是的,控制较少)。但这种方式的好处是我可以轻松地更改服务中的任何内容,并且在我的客户端自动点击一个regnerated代理。

    我希望有人可以解释一下为什么我应该这样做的好处,以及为什么其他Async方法的实现并非如此。

    谢谢你

    干杯

0 个答案:

没有答案