2015-09-21 84 views
2

下面你可以看到我的SignalR自托管中心的简化版本,在Windows服务:存储特定客户端的连接ID在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); 
    } 
} 

而且我有两种类型的客户为中心的:其中之一是Web应用程序,另一个是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标志被更改为SubscribeToPriceFeedUnsubscribeFromPriceFeed methods。

如果你仔细看,你在SubscribeToPriceFeed看到下面的一行:

context.Clients.All.updatePriceSubscriptionStatus(真);

我不想将消息发送给所有客户端,但我的客户端Windows服务。如何将特定客户端的连接ID存储在我的集线器中?如果我能做到这一点,我知道我可以发送短信到特定的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(); 
} 

创建一类无线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 TaskRelated(){ return base.OnConnected(); } –