[英]wcf callback reference
我有一個帶有雙工WCF服務的桌面應用程序,但是使用回調存在一些麻煩。
該服務在program.cs的主要部分中按以下方式啟動:
ServiceHost svcHost = new ServiceHost(typeof(PeriodicService));
svcHost.Open();
Console.WriteLine("Available Endpoints :\n");
svcHost.Description.Endpoints.ToList().ForEach(endpoint => Console.WriteLine(endpoint.Address.ToString() + " -- " + endpoint.Name));
對於該服務,我創建了一個訂閱函數,其中回調通道保存在全局變量中,然后回調使用該全局變量與客戶端進行通訊(只有一個客戶端在連接)。
IPeriodicCallback callbackClient;
public IPeriodicCallback Proxy
{
get
{
return this.callbackClient;
}
}
public void joinPeriodicService()
{
Console.WriteLine("Client subscribe");
this.callbackClient = OperationContext.Current.GetCallbackChannel<IPeriodicCallback>();
}
我現在想做的是從另一個類中調用callbackclient。 在另一個類中,我將服務創建為:
private PeriodicService periodicService = new PeriodicService();
我嘗試使用以下方法向其中寫入數據:
if(this.periodicService.Proxy != null)
{
this.periodicService.Proxy.On1MinuteDataAvailable(tmpPeriod);
}
但是,代理保持為空,我也嘗試將代理部分移至類,但這也導致其保持為空。
當客戶端連接時,我很好地收到消息“客戶端訂閱”,但似乎有兩個實例正在運行periodicservice。
但是我的問題是我沒有看到其他訪問周期服務的方法,然后在我的類中創建它,或者它是否已經由svcHost創建?
誰能指出我正確的方向?
該存儲庫顯示了我之前回答類似問題的雙工WCF實現,它是一個完整的工作示例,並盡可能減少了額外的工作量。
https://github.com/Aelphaeis/MyWcfDuplexPipeExample
可以說我們有這樣的服務合同:
[ServiceContract(CallbackContract = typeof(IMyServiceCallback),SessionMode = SessionMode.Required)]
public interface IMyService
{
[OperationContract(IsOneWay=true)]
void DoWork();
}
請注意,我指定了一個CallbackContract。 如果要進行雙工,則可能希望使上述合同的服務行為實現如下:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class MyService : IMyService
{
public void DoWork()
{
Console.WriteLine("Hello World");
Callback.WorkComplete();
}
IMyServiceCallback Callback
{
get
{
return OperationContext.Current.GetCallbackChannel<IMyServiceCallback>();
}
}
}
這里重要的是回調。 這就是您的服務將允許您訪問客戶端指定給您的方式。
您還需要定義回調接口,就我而言,它非常簡單:
[ServiceContract]
public interface IMyServiceCallback
{
[OperationContract(IsOneWay = true)]
void WorkComplete();
}
現在,我想創建一個客戶端來使用此雙工服務。 我需要做的第一件事是實現IMyServiceCallback。 我需要在客戶端上執行此操作。 在這種情況下,實現是這樣的:
class Callback : IMyServiceCallback
{
public void WorkComplete()
{
Console.WriteLine("Work Complete");
}
}
現在,當我想打開與服務的雙工連接時,我將創建一個像這樣的代理類:
public class MyServiceClient: IMyService, IDisposable
{
DuplexChannelFactory<IMyService> myServiceFactory { get; set; }
public MyServiceClient(IMyServiceCallback Callback)
{
InstanceContext site = new InstanceContext(Callback);
NetNamedPipeBinding binding = new NetNamedPipeBinding();
EndpointAddress endpointAddress = new EndpointAddress(Constants.myPipeService + @"/" + Constants.myPipeServiceName);
myServiceFactory = new DuplexChannelFactory<IMyService>(site, binding, endpointAddress);
}
public void DoWork()
{
myServiceFactory.CreateChannel().DoWork();
}
public void Dispose()
{
myServiceFactory.Close();
}
}
注意,我指定了InstanceContext。 該實例上下文將是我創建的實現IMyServiceCallback的對象的實例。
這就是您需要做的! 就那么簡單!
更新 :回調對象與其他任何對象一樣。 您可以將它們存儲到一個集合中,並根據某種條件遍歷它們。
一種方法是在IMyServiceCallback中創建可以唯一標識它的屬性。 當客戶端連接到服務時,它可以調用一個方法,該方法指定一個回調對象,然后可以將其緩存或保存以供以后使用。 然后,您可以迭代回調,並根據某些條件可以為特定客戶端調用方法。
這當然更加復雜。 但是,它肯定是可管理的。 我將添加一個示例。
更新2這是您想要的實際示例。 但是,它要復雜得多。 我將嘗試盡可能簡單地進行解釋: https : //github.com/Aelphaeis/MyWcfDuplexPipeExample/tree/MultiClient
以下是更改列表:
在代理類中,我有以下內容:
public MyServiceClient(IMyServiceCallback Callback)
{
InstanceContext site = new InstanceContext(Callback);
NetNamedPipeBinding binding = new NetNamedPipeBinding();
EndpointAddress endpointAddress = new EndpointAddress(Constants.myPipeService + @"/" + Constants.myPipeServiceName);
myServiceFactory = new DuplexChannelFactory<IMyService>(site, binding, endpointAddress);
Init();
}
public void Init()
{
myServiceFactory.CreateChannel().Init();
}
為我服務:
public class MyService : IMyService
{
public List<IMyServiceCallback> Callbacks { get; private set; }
public MyService(){
Callbacks = new List<IMyServiceCallback>();
}
public void Init()
{
Callbacks.Add(Callback);
}
// and so on
我的IMyServiceCallback已重新定義為:
[ServiceContract]
public interface IMyServiceCallback
{
[OperationContract]
int GetClientId();
[OperationContract(IsOneWay = true)]
void WorkComplete();
[OperationContract(IsOneWay = true)]
void RecieveMessage(String msg);
}
通過指定一個號碼,您可以聯系與該號碼相對應的客戶。 如果兩個客戶具有相同的ID,則將聯系這兩個客戶。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.