Open rainit2006 opened 7 years ago
WCFには、3種類の通信方法があります。
要求/応答パターン 一方向通信パターン 双方向通信パターン(非同期)
http://www.cnblogs.com/iamlilinfeng/archive/2012/09/25/2700049.html
在WCF中的接口与普通接口的区别只在于两个上下文 [ServiceContract] :来说明接口是一个WCF的接口,如果不加的话,将不能被外部调用。 [OperationContract]:来说明该方法是一个WCF接口的方法,不加的话同上。
WCF has a multi-layered architecture namely Contracts layer, Service Runtime Layer, Messaging Layer and Activation and Hosting Layer.
Contracts Layer Data Contract: Agreement between a service and a client on the data that has to be exchanged. Message Contract: Provides control over the SOAP messages that are produced and consumed by WCF. Service Contract: Defines the kind of operations supported by the service. Policy and Binding: Specify important information such as security, protocol.
Service Runtime layer specifies and manages different behaviors of the service that occur during the service operation.
Messaging Layer: It's composed of components and channels.
Hosting and Application Layer: This layer provides a number of options in which a service can be activated and hosted. Hosting can be of 2 types: self hosting, hosting on external agents, such as IIS.
Features of WCF can be described as follows:
Endpoint Support ・Addresses to locate the service ・Bindings to communicate with the service ・Contracts to specify the functionalities to be performed while communicating with the service. ・Endpoint behaviors to specify the runtime behavior of the service endpoint. These Addresses, Bindings and Contracts are normally referred to as ABC's of WCF.
Improved Transport Layer
Queuing Support
Improved Transactional process
Improved Security
Hosting Support on various environments
AJAX Integration and JSON Support
NamedPipe 1, 新建一个“WcfServiceLibrary1” 项目
namespace WcfServiceLibrary1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
string sayHello();
}
public class Service1 : IService1
{
public string sayHello()
{
return "HEllO!";
}
}
- App.config (也可以不设定,这样需要在server host端的代码里实现)
双方向コントラクト
To create a duplex contract 1, Create the interface that makes up the server side 2, Create the callback interface that defines the set of operations that the service can invoke on the client.
namespace WcfServiceLibrary1
{
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode = SessionMode.Required, CallbackContract = typeof(ISendDataCallBack))]
public interface IService1
{
[OperationContract(IsOneWay = true)]
void GetData(int value);
[OperationContract(IsOneWay = true)]
void sayHello(string data);
// TODO: Add your service operations here
}
public interface ISendDataCallBack
{
[OperationContract(IsOneWay = true)]
void getCallback(string data);
}
}
Server端代码
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class Service1 : IService1
{
public ISendDataCallBack callback = null;
public Service1()
{
callback = OperationContext.Current.GetCallbackChannel<ISendDataCallBack>();
}
public void GetData(int value)
{
// string.Format("You entered: {0}", value);
}
public void sayHello(string data)
{
callback = OperationContext.Current.GetCallbackChannel<ISendDataCallBack>();
Console.WriteLine(data);
callback.getCallback("Hello, this is server.");
return;
}
}
Server Host端代码
static void Main(string[] args)
{
//NetNamedPipeBinding namedPipe = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
ServiceHost host = new ServiceHost(typeof(WcfServiceLibrary1.Service1),
new Uri("net.pipe://localhost/WcfServiceLibrary1/Service1"));
try
{
//host.AddServiceEndpoint(typeof(WcfServiceLibrary1.IService1), new NetNamedPipeBinding(), "IService1");
// Open the service host to accept incoming calls
host.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
// Close the ServiceHostBase to shutdown the service.
host.Close();
}
Client
class ClientProgram : ISendDataCallBack
{
public string message = "null";
public IService1 channel = null;
public void getCallback(string data)
{
message = data;
Console.WriteLine(message);
}
}
Client host端代码
static void Main(string[] args)
{
ClientProgram client = new ClientProgram();
Thread.Sleep(5000);
//client.Create();
DuplexChannelFactory<WcfServiceLibrary1.IService1> factory = new DuplexChannelFactory<WcfServiceLibrary1.IService1>(new InstanceContext(client));
factory.Endpoint.Binding = new NetNamedPipeBinding();
factory.Endpoint.Contract.ContractType = typeof(WcfServiceLibrary1.IService1);
factory.Endpoint.Address = new EndpointAddress("net.pipe://localhost/WcfServiceLibrary1/Service1");
var channel = factory.CreateChannel();
channel.sayHello("client");
Console.WriteLine(client.message);
Console.Read();
}
注意: Debug的时候 Client程序经常报 错说,没有找到endpoint。所以不建议通过visual studio同时启动server host和client host,而是从debug/bin目录里先启动server host再 通过visual studio单独调试client端比较好。
利用DuplexBase
主要是更改client端,生成两个class。
class ClientProgram : DuplexClientBase<IService1>, IService1
{
public IService1 channel = null;
public ClientProgram(InstanceContext callbackCntx)
: base(callbackCntx, new NetNamedPipeBinding(),
new EndpointAddress("net.pipe://localhost/WcfServiceLibrary1/Service1"))
{
}
public void GetData(int data)
{
base.Channel.GetData(data);
}
public void sayHello(string data)
{
base.Channel.sayHello(data);
}
}
class clientCallback : ISendDataCallBack
{
public string message = "null";
public void getCallback(string data)
{
message = data;
Console.WriteLine(message);
}
}
client host端
static void Main(string[] args)
{
clientCallback callback = new clientCallback();
InstanceContext cntx = new InstanceContext(callback);
ClientProgram proxy = new ClientProgram(cntx);
proxy.sayHello("client proxy");
Console.WriteLine(callback.message);
Console.Read();
}
ClientBase