ASP.NET Průvodce rozhraním API služby SignalR Hubs – klient .NET (SignalR 1.x)

Patrick Fletcher, Tom Dykstra

Upozornění

Tato dokumentace není určená pro nejnovější verzi služby SignalR. Podívejte se na ASP.NET Core SignalR.

Tento dokument obsahuje úvod do používání rozhraní API služby Hubs pro SignalR verze 2 v klientech .NET, jako jsou aplikace Windows Store (WinRT), WPF, Silverlight a konzolové aplikace.

Rozhraní API služby SignalR Hubs umožňuje vzdáleně volat proceduru (RPC) ze serveru do připojených klientů a z klientů na server. V kódu serveru definujete metody, které mohou být voláni klienty, a voláte metody, které běží na klientovi. V klientském kódu definujete metody, které lze volat ze serveru, a voláte metody, které běží na serveru. SignalR se postará o veškeré instalace klient-server za vás.

SignalR také nabízí rozhraní API nižší úrovně označované jako trvalá připojení. Úvod do služby SignalR, center a trvalých připojení nebo kurz, který ukazuje, jak sestavit kompletní aplikaci SignalR, najdete v tématu SignalR – Začínáme.

Přehled

Tento dokument obsahuje následující části:

Ukázkové klientské projekty .NET najdete v následujících zdrojích informací:

Dokumentaci k naprogramování serverových nebo javascriptových klientů najdete v následujících zdrojích informací:

Odkazy na témata referenčních informací k rozhraní API jsou na verzi rozhraní API .NET 4.5. Pokud používáte .NET 4, projděte si témata týkající se rozhraní API verze .NET 4.

Nastavení klienta

Nainstalujte balíček NuGet Microsoft.AspNet.SignalR.Client (ne balíček Microsoft.AspNet.SignalR ). Tento balíček podporuje WinRT, Silverlight, WPF, konzolovou aplikaci a klienty Windows Phone pro .NET 4 i .NET 4.5.

Pokud se verze služby SignalR, kterou máte na klientovi, liší od verze, kterou máte na serveru, signalR se často dokáže rozdílu přizpůsobit. Pokud je například vydána služba SignalR verze 2.0 a nainstalujete ji na server, bude server podporovat klienty s nainstalovanou verzí 1.1.x i klienty s nainstalovanou verzí 2.0. Pokud je rozdíl mezi verzí na serveru a verzí na klientovi příliš velký, signalR vyvolá výjimku InvalidOperationException , když se klient pokusí navázat připojení. Chybová zpráva je "You are using a version of the client that isn't compatible with the server. Client version X.X, server version X.X".

Jak navázat připojení

Než budete moct navázat připojení, musíte vytvořit HubConnection objekt a vytvořit proxy server. Chcete-li navázat připojení, zavolejte metodu Start pro HubConnection objekt .

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();

Poznámka

Pro klienty JavaScriptu musíte před voláním Start metody pro navázání připojení zaregistrovat alespoň jednu obslužnou rutinu události. Pro klienty .NET to není nutné. Pro klienty JavaScriptu vygenerovaný proxy kód automaticky vytvoří proxy servery pro všechna centra, která existují na serveru, a registrací obslužné rutiny určíte, která centra chce váš klient použít. Pro klienta .NET ale proxy služby Hub vytváříte ručně, takže SignalR předpokládá, že budete používat jakékoli centrum, pro které vytvoříte proxy server.

Ukázkový kód používá pro připojení ke službě SignalR výchozí adresu URL /signalr. Informace o tom, jak zadat jinou základní adresu URL, najdete v tématu Průvodce rozhraním API služby ASP.NET SignalR Hubs – Server – Adresa URL /signalr.

Metoda provádí Start asynchronně. Pokud chcete zajistit, aby se následující řádky kódu nespustí až po navázání připojení, použijte await v ASP.NET 4.5 asynchronní metodu nebo .Wait() synchronní metodu. Nepoužívejte .Wait() v klientovi WinRT.

await connection.Start();
connection.Start().Wait();

Třída HubConnection je bezpečná pro přístup z více vláken.

Mezidoménová připojení z klientů Silverlight

Informace o tom, jak povolit připojení mezi doménami z klientů Silverlight, najdete v tématu Zpřístupnění služby napříč hranicemi domény.

Jak nakonfigurovat připojení

Před navázáním připojení můžete zadat některou z následujících možností:

  • Limit souběžných připojení.
  • Parametry řetězce dotazu.
  • Způsob přenosu.
  • Hlavičky PROTOKOLU HTTP.
  • Klientské certifikáty.

Nastavení maximálního počtu souběžných připojení v klientech WPF

V klientech WPF možná budete muset zvýšit maximální počet souběžných připojení z výchozí hodnoty 2. Doporučená hodnota je 10.

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();

Další informace najdete v tématu ServicePointManager.DefaultConnectionLimit.

Jak zadat parametry řetězce dotazu

Pokud chcete odeslat data na server, když se klient připojí, můžete do objektu připojení přidat parametry řetězce dotazu. Následující příklad ukazuje, jak nastavit parametr řetězce dotazu v kódu klienta.

var querystringData = new Dictionary<string, string>();
querystringData.Add("contosochatversion", "1.0");
var connection = new HubConnection("http://contoso.com/", querystringData);

Následující příklad ukazuje, jak přečíst parametr řetězce dotazu v kódu serveru.

public class StockTickerHub : Hub
{
    public override Task OnConnected()
    {
        var version = Context.QueryString["contosochatversion"];
        if (version != "1.0")
        {
            Clients.Caller.notifyWrongVersion();
        }
        return base.OnConnected();
    }
}

Jak zadat metodu přenosu

V rámci procesu připojení klient SignalR obvykle vyjednává se serverem, aby určil nejlepší přenos podporovaný serverem i klientem. Pokud už víte, který přenos chcete použít, můžete tento proces vyjednávání obejít. Chcete-li určit metodu přenosu, předejte transportní objekt metodě Start. Následující příklad ukazuje, jak zadat metodu přenosu v kódu klienta.

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());

Obor názvů Microsoft.AspNet.SignalR.Client.Transports obsahuje následující třídy, které můžete použít k určení přenosu.

Přenos ForeverFrame není součástí tohoto seznamu, protože ho používají jenom prohlížeče.

Informace o tom, jak zkontrolovat metodu přenosu v kódu serveru, najdete v tématu ASP.NET Průvodce rozhraním API služby SignalR Hubs – Server – Jak získat informace o klientovi z vlastnosti Context. Další informace o přenosech a náhradních přenosech najdete v tématu Úvod do SignalR – Přenosy a záložní služby.

Jak zadat hlavičky HTTP

Pokud chcete nastavit hlavičky PROTOKOLU HTTP, použijte Headers vlastnost u objektu connection. Následující příklad ukazuje, jak přidat hlavičku HTTP.

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();

Jak zadat klientské certifikáty

Pokud chcete přidat klientské certifikáty, použijte metodu AddClientCertificate pro objekt připojení.

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();

Vytvoření proxy serveru centra

Chcete-li definovat metody v klientovi, které může centrum volat ze serveru, a vyvolat metody v centru na serveru, vytvořte proxy pro centrum voláním CreateHubProxy na objekt připojení. Řetězec, do který předáte CreateHubProxy , je název vaší třídy Hub nebo název zadaný atributem HubName , pokud byl použit na serveru. Porovnávání názvů nerozlišuje velká a malá písmena.

Třída hubu na serveru

public class StockTickerHub : Hub

Vytvoření klientského proxy serveru pro třídu 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();

Pokud třídu Hubu ozdobíte atributem HubName , použijte tento název.

Třída hubu na serveru

[HubName("stockTicker")]
public class StockTickerHub : Hub

Vytvoření klientského proxy serveru pro třídu 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();

Objekt proxy serveru je bezpečný pro přístup z více vláken. Ve skutečnosti, pokud zavoláte HubConnection.CreateHubProxy vícekrát se stejným hubNameobjektem , získáte stejný objekt v IHubProxy mezipaměti.

Jak definovat metody v klientovi, které server může volat

Chcete-li definovat metodu, kterou může server volat, použijte metodu proxy On k registraci obslužné rutiny události.

Porovnávání názvů metod nerozlišuje velká a malá písmena. Například Clients.All.UpdateStockPrice na serveru se spustí updateStockPrice, updatestockpricenebo UpdateStockPrice na klientovi.

Různé klientské platformy mají různé požadavky na způsob psaní kódu metody pro aktualizaci uživatelského rozhraní. Uvedené příklady jsou pro klienty WinRT (Windows Store .NET). Příklady aplikací WPF, Silverlight a konzolových aplikací najdete v samostatné části dále v tomto tématu.

Metody bez parametrů

Pokud metoda, kterou zpracováváte, nemá parametry, použijte jiné než obecné přetížení On metody:

Kód serveru volající metodu klienta bez parametrů

public class StockTickerHub : Hub
{
    public void NotifyAllClients()
    {
         Clients.All.Notify();
    }
}

Kód klienta WinRT pro metodu volanou ze serveru bez parametrů (viz příklady WPF a Silverlight dále v tomto tématu).

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();

Metody s parametry, určení typů parametrů

Pokud metoda, kterou zpracováváte, obsahuje parametry, zadejte typy parametrů jako obecné typy On metody. Existují obecná přetížení On metody, která umožňují zadat až 8 parametrů (4 na Windows Phone 7). V následujícím příkladu se metodě odešle UpdateStockPrice jeden parametr.

Kód serveru volající metodu klienta s parametrem

public void BroadcastStockPrice(Stock stock)
{
    context.Clients.Others.UpdateStockPrice(stock);
}

Třída Stock použitá pro parametr

public class Stock
{
    public string Symbol { get; set; }
    public decimal Price { get; set; }
}

Kód klienta WinRT pro metodu volanou ze serveru s parametrem (viz příklady WPF a Silverlight dále v tomto tématu).

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)
);

Metody s parametry, určení dynamických objektů pro parametry

Jako alternativu k zadání parametrů jako obecných typů On metody můžete zadat parametry jako dynamické objekty:

Kód serveru volající metodu klienta s parametrem

public void BroadcastStockPrice(Stock stock)
{
    context.Clients.Others.UpdateStockPrice(stock);
}

Třída Stock použitá pro parametr

public class Stock
{
    public string Symbol { get; set; }
    public decimal Price { get; set; }
}

Kód klienta WinRT pro metodu volanou ze serveru s parametrem pomocí dynamického objektu pro parametr (viz příklady WPF a Silverlight dále v tomto tématu).

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)
);

Odebrání obslužné rutiny

Chcete-li odebrat obslužnou rutinu, zavolejte její Dispose metodu.

Kód klienta pro metodu volanou ze serveru

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)
);

Kód klienta pro odebrání obslužné rutiny

updateStockPriceHandler.Dispose();

Volání metod serveru z klienta

Pokud chcete volat metodu na serveru, použijte metodu Invoke na proxy serveru centra.

Pokud metoda serveru nemá žádnou návratovou hodnotu, použijte negenerní přetížení Invoke metody.

Kód serveru pro metodu, která nemá žádnou návratovou hodnotu

public class StockTickerHub : Hub
{
    public void JoinGroup(string groupName)
    {
        Groups.Add(Context.ConnectionId, groupName); 
    }
}

Kód klienta volající metodu, která nemá žádnou návratovou hodnotu

stockTickerHubProxy.Invoke("JoinGroup", hubConnection.ConnectionID, "SignalRChatRoom");

Pokud má metoda serveru návratovou hodnotu, zadejte návratový typ jako obecný typ Invoke metody.

Kód serveru pro metodu, která má návratovou hodnotu a přebírá parametr komplexního typu

public IEnumerable<Stock> AddStock(Stock stock)
{
    _stockTicker.AddStock(stock);
    return _stockTicker.GetAllStocks();
}

Třída Stock použitá pro parametr a návratnou hodnotu

public class Stock
{
    public string Symbol { get; set; }
    public decimal Price { get; set; }
}

Kód klienta volající metodu, která má návratovou hodnotu a přebírá parametr komplexního typu v asynchronní metodě ASP.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);
}

Klientský kód volající metodu, která má návratovou hodnotu a přebírá parametr komplexního typu v synchronní metodě

var stocks = stockTickerHub.Invoke<IEnumerable<Stock>>("AddStock", new Stock() { Symbol = "MSFT" }).Result;
foreach (Stock stock in stocks)
{
    textBox.Text += string.Format("Symbol: {0} price: {1}\n", stock.Symbol, stock.Price);
}

Metoda Invoke provede asynchronně a vrátí Task objekt. Pokud nezadáte await nebo .Wait(), spustí se další řádek kódu před dokončením provádění metody, kterou vyvoláte.

Zpracování událostí životnosti připojení

SignalR poskytuje následující události životnosti připojení, které můžete zpracovat:

  • Received: Vyvolána při přijetí jakýchkoli dat v připojení. Poskytuje přijatá data.
  • ConnectionSlow: Vyvolána, když klient zjistí pomalé nebo často zapadající připojení.
  • Reconnecting: Vyvolá se, když se základní přenos začne znovu připojovat.
  • Reconnected: Vyvoláno při opětovném připojení základního přenosu.
  • StateChanged: Vyvolána při změně stavu připojení. Poskytuje starý stav a nový stav. Informace o hodnotách stavu připojení najdete v tématu ConnectionState – výčet.
  • Closed: Vyvoláno, když se připojení odpojí.

Pokud například chcete zobrazit varovné zprávy pro chyby, které nejsou závažné, ale způsobují přerušované problémy s připojením, jako je zpomalení nebo časté ukončení připojení, zpracujte událost ConnectionSlow .

hubConnection.ConnectionSlow += () => Console.WriteLine("Connection problems.");

Další informace najdete v tématu Vysvětlení a zpracování událostí životnosti připojení v SignalR.

Zpracování chyb

Pokud na serveru explicitně nepovolíte podrobné chybové zprávy, objekt výjimky, který SignalR vrátí po chybě, obsahuje minimální informace o chybě. Pokud například volání newContosoChatMessage selže, chybová zpráva v objektu chyby obsahuje "There was an error invoking Hub method 'contosoChatHub.newContosoChatMessage'." Odesílání podrobných chybových zpráv klientům v produkčním prostředí se z bezpečnostních důvodů nedoporučuje, ale pokud chcete povolit podrobné chybové zprávy pro účely řešení potíží, použijte na serveru následující kód.

var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableDetailedErrors = true;
RouteTable.Routes.MapHubs(hubConfiguration);

Pokud chcete zpracovat chyby, které signalR vyvolává, můžete přidat obslužnou rutinu Error události do objektu připojení.

hubConnection.Error += ex => Console.WriteLine("SignalR error: {0}", ex.Message);

Pokud chcete zpracovat chyby při vyvolání metody, zabalte kód do bloku 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);
}

Povolení protokolování na straně klienta

Pokud chcete povolit protokolování na straně klienta, nastavte TraceLevel vlastnosti a TraceWriter objektu připojení.

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();

Ukázky kódu aplikací WPF, Silverlight a konzoly pro klientské metody, které může server volat

Ukázky kódu uvedené dříve pro definování klientských metod, které server může volat, platí pro klienty WinRT. Následující ukázky ukazují ekvivalentní kód pro klienty aplikací WPF, Silverlight a konzolových aplikací.

Metody bez parametrů

Kód klienta WPF pro metodu volanou ze serveru bez parametrů

stockTickerHub.On<Stock>("notify", () =>
    Dispatcher.InvokeAsync(() =>
        {
            SignalRTextBlock.Text += string.Format("Notified!");
        })
);

Kód klienta Silverlight pro metodu volanou ze serveru bez parametrů

stockTickerHub.On<Stock>("notify", () =>
    // Context is a reference to SynchronizationContext.Current
    Context.Post(delegate
    {
        textBox.Text += "Notified!";
    }, null)
);

Kód klienta konzolové aplikace pro metodu volanou ze serveru bez parametrů

stockTickerHubProxyProxy.On("Notify", () => Console.WriteLine("Notified!"));

Metody s parametry, určení typů parametrů

Kód klienta WPF pro metodu volanou ze serveru s parametrem

stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => 
    Dispatcher.InvokeAsync(() =>
        {
            textBox.Text += string.Format("Stock update for {0} new price {1}\n", stock.Symbol, stock.Price);
        })
);

Kód klienta Silverlight pro metodu volanou ze serveru s parametrem

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)
);

Kód klienta konzolové aplikace pro metodu volanou ze serveru s parametrem

stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => 
    Console.WriteLine("Symbol {0} Price {1}", stock.Symbol, stock.Price));

Metody s parametry, určení dynamických objektů pro parametry

Kód klienta WPF pro metodu volanou ze serveru s parametrem pomocí dynamického objektu pro parametr

stockTickerHubProxy.On("UpdateStockPrice", stock => 
    Dispatcher.InvokeAsync(() =>
        {
            textBox.Text += string.Format("Stock update for {0} new price {1}\n", stock.Symbol, stock.Price);
        })
);

Kód klienta Silverlight pro metodu volanou ze serveru s parametrem pomocí dynamického objektu pro parametr

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)
);

Kód klienta konzolové aplikace pro metodu volanou ze serveru s parametrem pomocí dynamického objektu pro parametr

stockTickerHubProxy.On("UpdateStockPrice", stock => 
    Console.WriteLine("Symbol {0} Price {1}", stock.Symbol, stock.Price));