Ниже упрощенная версию моего SignalR самодостаточен концентратор службы окон:Сохранения соединения идентификатора конкретного клиента в SignalR ступице
public static class SubscriptionHandler
{
public static int PriceFeedMembersCount = 0;
}
public class PriceHub : Hub
{
public Task SubscribeToPriceFeed()
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<PriceHub>();
if (SubscriptionHandler.PriceFeedMembersCount == 0)
{
context.Clients.All.updatePriceSubscriptionStatus(true);
}
SubscriptionHandler.PriceFeedMembersCount++;
return context.Groups.Add(Context.ConnectionId, "PriceFeed");
}
public Task UnsubscribeFromPriceFeed()
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<PriceHub>();
SubscriptionHandler.PriceFeedMembersCount--;
if (SubscriptionHandler.PriceFeedMembersCount == 0)
{
context.Clients.All.updatePriceSubscriptionStatus(false);
}
return context.Groups.Remove(Context.ConnectionId, "PriceFeed");
}
public void NotifySubscribers(Price price)
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<PriceHub>();
context.Clients.Group("PriceFeed").updatePrice(price);
}
}
И у меня есть два типа клиентов для этого хаба: Один из них - это веб-приложения, а другой - службы Windows. Здесь вы можете увидеть демонстрационную реализацию моей службы окон в качестве клиента signalr:
public partial class WinSer45 : ServiceBase
{
private HubConnection hubConnection;
private IHubProxy priceProxy;
private Timer timer = new Timer();
private bool hasSubscribers = false;
public WinSer45()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
timer.Interval = 1000; // saniyede bir
timer.Elapsed += timer_Elapsed;
timer.Enabled = true;
hubConnection = new HubConnection("http://localhost:8080/signalr", useDefaultUrl: false);
priceProxy = hubConnection.CreateHubProxy("PriceHub");
hubConnection.Start().Wait();
priceProxy.On<bool>("UpdatePriceSubscriptionStatus", hasSubscribers =>
{
this.hasSubscribers = hasSubscribers;
});
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (hasSubscribers)
{
TestPrice testPrice = new TestPrice() { Id = 1, Buy = 1.2345, Sell = 9.8765, Symbol = "EURUSD" };
priceProxy.Invoke("NotifySubscribers", testPrice).Wait();
}
}
protected override void OnStop()
{
}
}
Как вы видите, я использую hasSubscribers флаг, чтобы минимизировать сообщения между ступицей и клиентами. И флаг hasSubscribers изменен на Подписаться на рассылку и Отказаться от подписейFromPriceFeed методов.
Если вы внимательно посмотрите, то увидите строку ниже в SubscribeToPriceFeed:
context.Clients.All.updatePriceSubscriptionStatus (истина);
Я не хочу отправлять сообщение всем клиентам, кроме службы моих клиентов. Как сохранить идентификатор соединения конкретного клиента в моем концентраторе? Если я могу сделать это, я знаю, что я могу отправить сообщение конкретному ConnectionID как в строке ниже:
context.Clients.Client (ConnectionID) .updatePriceSubscriptionStatus (истина);
Заранее спасибо, источник
Запомните: public override Задача OnReconnected() { return base.OnConnected(); } –