Establish a SignalR connection
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();
Configure SignalR connections
Set the maximum connection in the WPF client
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 = 10; await hubConnection.Start();
Setting Query String parameters
var querystringData = new Dictionary<string, string>(); querystringData.Add("contosochatversion", "1.0"); var connection = new HubConnection("http://contoso.com/", querystringData);
Read 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(); } }
Designated transport protocol
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());
You can specify the following four ways
- LongPollingTransport
- ServerSentEventsTransport
- WebSocket Transport (only if both server and client use. NET 4.5)
- AutoTransport
Specify 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();
Specify Client certificate
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();
Create Hub proxy
Server side
public class StockTickerHub : Hub
Client
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();
If your HubName class uses the HubName feature, you need to use the HubName value to invoke it.
Server side
[HubName("stockTicker")] public class StockTickerHub : Hub
Client
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();
If you call HubConnection.CreateHubProxy multiple times using HubName, you get the same IHubProxy object cached.
How to define Client method invoked on Server side
No reference method
Server terminal
public class StockTickerHub : Hub { public void NotifyAllClients() { Clients.All.Notify(); } }
Client
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();
Specified parameter type with parameters
Sever terminal
public void BroadcastStockPrice(Stock stock) { context.Clients.Others.UpdateStockPrice(stock); }
Stock class as a parameter
public class Stock
{
public string Symbol { get; set; }
public decimal Price { get; set; }
}
Client code
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) );
With parameters, specify dynamic types
server terminal
public void BroadcastStockPrice(Stock stock) { context.Clients.Others.UpdateStockPrice(stock); }
Stock class as a parameter
public class Stock { public string Symbol { get; set; } public decimal Price { get; set; } }
Client code
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) );
Remove 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();
Calling the server-side method from the client
Use HubProxy's Invoke method to invoke the method on the server side.
The server-side method does not return a value
public class StockTickerHub : Hub { public void JoinGroup(string groupName) { Groups.Add(Context.ConnectionId, groupName); } }
Client invokes a method where the server does not return a value
stockTickerHubProxy.Invoke("JoinGroup", "SignalRChatRoom");
Server-side methods have return values and have a complex type of parameter
public IEnumerable<Stock> AddStock(Stock stock) { _stockTicker.AddStock(stock); return _stockTicker.GetAllStocks(); }
Class Stock
public class Stock { public string Symbol { get; set; } public decimal Price { get; set; } }
Client calls methods with return values and complex type parameters, and asynchronous methods are used in. 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); }
How to handle connection life cycle events
SignalR provides the following life cycle events that you can capture.
- received: executes when any data is acquired through a connection. Data are available.
- connectionSlow: Executes when the client detects slow or unfluent connections.
- reconnecting: Executes when a potential protocol restarts the connection.
- reconnected: Executes when potential protocols and reconnects are re-established.
- stateChanged: Executes when the state of the connection changes. You can provide an old and new state (Connecting, Connected, Reconnecting, or Disconnected).
- Closed: Executes when the connection is interrupted.
hubConnection.ConnectionSlow += () => Console.WriteLine("Connection problems.");
Capture exception
If you don't explicitly open detailed error messages on the server side, SignalR will only list some simple error messages. You can open detailed error information records through the following code.
var hubConfiguration = new HubConfiguration(); hubConfiguration.EnableDetailedErrors = true; App.MapSignalR(hubConfiguration);
Add an error to the connection object to handle events.
hubConnection.Error += ex => Console.WriteLine("SignalR error: {0}", ex.Message);
Catching exceptions with 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); }
Open client log
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();
Reference link:
https://docs.microsoft.com/zh-cn/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-net-client