我认为首先回答这个问题会让生活变得更轻松:
我怎么知道“这个”客户是什么?
OperationContext.Current.GetCallbackChannel<T>
对于服务接收到的每个调用,都会有一个客户端通道,通过该通道进行调用,这将为您提供仅进行该调用的客户端的回调通道,这是您能够区分客户端的简单方法.
关于整个场景的方法,我将首先按照您自己的建议将列表存储subscribers
在静态dictionary
中,但还要保留每个客户端回调实例及其用户名:
private static Dictionary<IPriceChangeCallback, string> subscribers = new Dictionary<IPriceChangeCallback, string>();
您的回调合同在哪里IPriceChangeCallback
,字符串可以是唯一的用户名或任何标识符。因此,您现在具有区分客户的基本能力,例如,假设您要将最后收到的消息发布给除发送者之外的每个客户,您将:
lock (subscribers)
{
foreach (var _subscriber in subscribers)
{
if (OperationContext.Current.GetCallbackChannel<IPriceChangeNotification>() == _subscriber.Key)
{
//if the person who sent the last message is the current subscriber, there is no need to
//publish the message to him, so skip this iteration
continue;
}
else
{
//GetCurrrentClient is a handy method, you can optionally include this
//in your callbacks just to let your clients know who exactly sent the publication
_subscriber.Key.PriceChangeCallback(e.Item, e.Price, e.Change, GetCurrentClient());
}
}
}
或根据用户名区分您的客户,理想情况下您也应该在数据库中拥有这些用户名:
lock (subscribers)
{
foreach (var _subscriber in subscribers)
{
if(_subscriber.Value == "Jimmy86"))
{
//Identify a specific client by their username and don't send the notification to him
//here we send the notification to everyone but jimmy86
continue;
}
else
{
_subscriber.Key.PriceChangeCallback(e.Item, e.Price, e.Change, GetCurrentClient());
}
}
}
再说一次,每当你想知道是谁调用了服务操作,并告诉你的客户是谁发送了那个特定的消息,使用GetCurrentClient()
我之前提到的方法:
private string GetCurrentClient()
{
return clients[OperationContext.Current.GetCallbackChannel<IPriceChangeNotification>()];
}
这是正确的方法吗?
我不确定上面的方法有多可取,但我以前曾经做过,只要我想保留一个客户列表并在他们身上调用一些方法。
客户是否应该以我将存储的“订阅”方法向我发送凭据?
是的,这是一种常见的方法。对您的服务进行Subscribe()
操作,这将是您的客户在想要加入您的服务时调用的第一个方法:
[OperationContract(IsOneWay = true)]
public void Subscribe(string username)
{
lock (subscribers)
{
subscribers.Add(OperationContext.Current.GetCallbackChannel<IPriceChangeNotification>(), username);
}
}
几个月前,我正在开发 Pub/Sub Silverlight 服务,我发现这篇文章及其随附的视频非常宝贵。