正文
【SignalR学习系列】8. SignalR Hubs Api 详解(.Net C# 客户端)
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
建立一个 SignalR 连接var hubConnection = new HubConnection("http://www.contoso.com/");
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await hubConnection.Start();
配置 SignalR 连接在 WPF 客户端里设置连接的最大值
var hubConnection = new HubConnection("http://www.contoso.com/");
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
ServicePointManager.DefaultConnectionLimit = ;
await hubConnection.Start();
设置 Query String 参数
var querystringData = new Dictionary<string, string>();
querystringData.Add("contosochatversion", "1.0");
var connection = new HubConnection("http://contoso.com/", querystringData);
var hubConnection = new HubConnection("http://www.contoso.com/");
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await hubConnection.Start();
在 WPF 客户端里设置连接的最大值
var hubConnection = new HubConnection("http://www.contoso.com/");
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
ServicePointManager.DefaultConnectionLimit = ;
await hubConnection.Start();
设置 Query String 参数
var querystringData = new Dictionary<string, string>();
querystringData.Add("contosochatversion", "1.0");
var connection = new HubConnection("http://contoso.com/", querystringData);
读取 query string
public class StockTickerHub : Hub
{
public override Task OnConnected()
{
var version = Context.QueryString["contosochatversion"];
if (version != "1.0")
{
Clients.Caller.notifyWrongVersion();
}
return base.OnConnected();
}
}
指定传输协议
var hubConnection = new HubConnection("http://www.contoso.com/");
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await hubConnection.Start(new LongPollingTransport());
可以指定以下四种方式
- LongPollingTransport
- ServerSentEventsTransport
- WebSocketTransport (只有在 server and client 都使用 .NET 4.5的情况下才能使用)
- AutoTransport(自动选择)
指定 Http Header
hubConnection = new hubConnection("http://www.contoso.com/");
connection.Headers.Add("headername", "headervalue");
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await connection.Start();
指定 Client 证书
hubConnection = new hubConnection("http://www.contoso.com/");
hubConnection.AddClientCertificate(X509Certificate.CreateFromCertFile("MyCert.cer"));
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await connection.Start();
创建 Hub proxy
服务端
public class StockTickerHub : Hub
客户端
var hubConnection = new HubConnection("http://www.contoso.com/");
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await hubConnection.Start();
如果你的 Hub 类使用了 HubName 特性,那么就需要使用 HubName 的值来调用。
服务端
[HubName("stockTicker")]
public class StockTickerHub : Hub
客户端
var hubConnection = new HubConnection("http://www.contoso.com/");
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("stockTicker");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock =>
Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await hubConnection.Start();
如果使用 HubName 多次调用 HubConnection.CreateHubProxy,那么会得到缓存的相同的 IHubProxy 对象。
如何定义在 Server 端调用的 Client 方法无参方法
Server 端
public class StockTickerHub : Hub
{
public void NotifyAllClients()
{
Clients.All.Notify();
}
}
客户端
var hubConnection = new HubConnection("http://www.contoso.com/");
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHub.On("notify", () =>
// Context is a reference to SynchronizationContext.Current
Context.Post(delegate
{
textBox.Text += "Notified!\n";
}, null)
);
await hubConnection.Start();
有参指定参数类型
Sever 端
public void BroadcastStockPrice(Stock stock)
{
context.Clients.Others.UpdateStockPrice(stock);
}
用作参数的 Stock 类
public class Stock
{
public string Symbol { get; set; }
public decimal Price { get; set; }
}
客户端代码
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock =>
// Context is a reference to SynchronizationContext.Current
Context.Post(delegate
{
textBox.Text += string.Format("Stock update for {0} new price {1}\n", stock.Symbol, stock.Price);
}, null)
);
有参,指定动态类型
server 端
public void BroadcastStockPrice(Stock stock)
{
context.Clients.Others.UpdateStockPrice(stock);
}
用作参数的 Stock 类
public class Stock
{
public string Symbol { get; set; }
public decimal Price { get; set; }
}
客户端代码
stockTickerHubProxy.On("UpdateStockPrice", stock =>
// Context is a reference to SynchronizationContext.Current
Context.Post(delegate
{
textBox.Text += string.Format("Stock update for {0} new price {1}\n", stock.Symbol, stock.Price);
}, null)
);
移除Handler
var updateStockPriceHandler = stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock =>
Context.Post(delegate
{
textBox.Text += string.Format("Stock update for {0} new price {1}\n", stock.Symbol, stock.Price);
}, null)
);updateStockPriceHandler.Dispose();
从客户端调用服务端方法
使用 HubProxy 的 Invoke 方法来调用服务端的方法。
服务端方法没有返回值
public class StockTickerHub : Hub
{
public void JoinGroup(string groupName)
{
Groups.Add(Context.ConnectionId, groupName);
}
}
客户端调用服务器没有返回值的方法
stockTickerHubProxy.Invoke("JoinGroup", "SignalRChatRoom");
服务端方法有返回值,并且有一个复杂类型的参数
public IEnumerable<Stock> AddStock(Stock stock)
{
_stockTicker.AddStock(stock);
return _stockTicker.GetAllStocks();
}
Stock 类
public class Stock
{
public string Symbol { get; set; }
public decimal Price { get; set; }
}
客户端调用有返回值和复杂类型参数的方法,.Net 4.5 里使用异步方法
var stocks = await stockTickerHub.Invoke<IEnumerable<Stock>>("AddStock", new Stock() { Symbol = "MSFT" });
foreach (Stock stock in stocks)
{
textBox.Text += string.Format("Symbol: {0} price: {1}\n", stock.Symbol, stock.Price);
}
如何处理连接的生命周期事件
SignalR 提供了下述你可以捕获的生命周期事件。
- received: 当任何数据通过连接获取到的时候执行。可以得到数据。
- connectionSlow: 当客户端检测到缓慢或者不流畅的连接的时候执行。
- reconnecting: 当潜在的协议重新开始连接的时候执行。
- reconnected: 当潜在的协议以及重新建立连接的时候执行。
- stateChanged: 当连接的状态发生改变的时候执行。可以提供一个旧的和新的状态(Connecting, Connected, Reconnecting, 或者 Disconnected)。
- Closed: 当连接中断以后执行。
hubConnection.ConnectionSlow += () => Console.WriteLine("Connection problems.");
捕获异常
如果你不在服务端明确地打开详细错误信息,那么SignalR只会列出一些简单的错误信息,你可以通过下面的代码开启详细错误信息记录。
var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableDetailedErrors = true;
App.MapSignalR(hubConfiguration);
给 connection 对象添加一个 error 处理事件。
hubConnection.Error += ex => Console.WriteLine("SignalR error: {0}", ex.Message);
用 try - catch 捕获异常
try
{
IEnumerable<Stock> stocks = await stockTickerHub.Invoke<IEnumerable<Stock>>("GetAllStocks");
foreach (Stock stock in stocks)
{
Console.WriteLine("Symbol: {0} price: {1}", stock.Symbol, stock.Price);
}
}
catch (Exception ex)
{
Console.WriteLine("Error invoking GetAllStocks: {0}", ex.Message);
}
开启客户端日志var hubConnection = new HubConnection("http://www.contoso.com/");
hubConnection.TraceLevel = TraceLevels.All;
hubConnection.TraceWriter = Console.Out;
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await hubConnection.Start();
参考链接:
var hubConnection = new HubConnection("http://www.contoso.com/");
hubConnection.TraceLevel = TraceLevels.All;
hubConnection.TraceWriter = Console.Out;
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await hubConnection.Start();
https://docs.microsoft.com/zh-cn/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-net-client