2015-09-21 3 views
2

Ниже упрощенная версию моего 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 (истина);

Заранее спасибо, источник

ответ

3

проход во время соединения

как этот

hubConnection = new HubConnection("http://localhost:8080/signalr","source=windows",useDefaultUrl: false); 

HUB

public override Task OnConnected() 
{ 
    var source= Context.QueryString['source']; 
    return base.OnConnected(); 
} 

создать класс, Wi LL держать пользователя с источником

public class user { 
    public string ConnectionID {set;get;} 
    public string Source {set;get;} 
} 

объявить список в ступице

List<user> userList=new List<user>(); 

Затем нажмите пользователя во время OnConnected

public override Task OnConnected() 
{ 
    var us=new user(); 
    us.Source = Context.QueryString['source']; 
    us.ConnectionID=Context.ConnectionId; 
    userList.Add(us); 
    return base.OnConnected(); 
} 

и во время трансляции только профильтровать источником

var windowsUser=userList.Where(o=>o.Source == "windows").ToList(); // you'll get the windows user list 
+0

Запомните: public override Задача OnReconnected() { return base.OnConnected(); } –