在 SignalR hub 中存储特定客户端的连接 ID
Storing the connection id of a specific client in SignalR hub
下面您可以看到我的 SignalR 自托管集线器在 windows 服务上的简化版本:
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 服务。在这里您可以看到我的 windows 服务作为信号器客户端的演示实现:
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 标志由 SubscribeToPriceFeed 和 UnsubscribeFromPriceFeed 方法更改。
如果仔细观察,您会在 SubscribeToPriceFeed 中看到以下行:
context.Clients.All.updatePriceSubscriptionStatus(true);
我不想将消息发送给所有客户端,但我的客户端 windows 服务。如何将特定客户端的连接 ID 存储在我的集线器中?如果我能做到这一点,我知道我可以将消息发送到特定的 connectionId,如下所示:
context.Clients.Client(connectionId).updatePriceSubscriptionStatus(true);
提前致谢,
在连接期间传递源
像这样
hubConnection = new HubConnection("http://localhost:8080/signalr","source=windows",useDefaultUrl: false);
HUB
public override Task OnConnected()
{
var source= Context.QueryString['source'];
return base.OnConnected();
}
创建一个 class 来保存用户和 source
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
下面您可以看到我的 SignalR 自托管集线器在 windows 服务上的简化版本:
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 服务。在这里您可以看到我的 windows 服务作为信号器客户端的演示实现:
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 标志由 SubscribeToPriceFeed 和 UnsubscribeFromPriceFeed 方法更改。
如果仔细观察,您会在 SubscribeToPriceFeed 中看到以下行:
context.Clients.All.updatePriceSubscriptionStatus(true);
我不想将消息发送给所有客户端,但我的客户端 windows 服务。如何将特定客户端的连接 ID 存储在我的集线器中?如果我能做到这一点,我知道我可以将消息发送到特定的 connectionId,如下所示:
context.Clients.Client(connectionId).updatePriceSubscriptionStatus(true);
提前致谢,
在连接期间传递源
像这样
hubConnection = new HubConnection("http://localhost:8080/signalr","source=windows",useDefaultUrl: false);
HUB
public override Task OnConnected()
{
var source= Context.QueryString['source'];
return base.OnConnected();
}
创建一个 class 来保存用户和 source
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