我尝试从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类与我生成的类进行比较,我得到的问题是我生成的类都不相同。
任何人都能解释我他做到了吗?这个理想的好处是什么?
我还尝试了服务参考方式,我认为这是最简单的方法(是的,控制较少)。但这种方式的好处是我可以轻松地更改服务中的任何内容,并且在我的客户端自动点击一个regnerated代理。
我希望有人可以解释一下为什么我应该这样做的好处,以及为什么其他Async方法的实现并非如此。
谢谢你
干杯