Przewodnik interfejsu API centrów sygnałów ASP.NET — serwer (C#)

Fletcher Patryk, Tomasz Dykstra

Warning

Ta dokumentacja nie jest najnowsza dla najnowszej wersji usługi sygnalizującej. Zapoznaj się z tematem ASP.NET Core sygnalizujący.

Ten dokument zawiera wprowadzenie do programowania po stronie serwera interfejsu API centrów ASP.NETer dla usługi sygnalizującego w wersji 2, z przykładami kodu pokazującymi typowe opcje.

Interfejs API centrów sygnałów umożliwia wykonywanie zdalnych wywołań procedur (RPC) z serwera do podłączonych klientów i od klientów do serwera programu. W polu kod serwera można zdefiniować metody, które mogą być wywoływane przez klientów, i wywoływanie metod uruchamianych na kliencie. W kodzie klienta należy zdefiniować metody, które mogą być wywoływane z serwera programu, i wywoływanie metod, które są uruchamiane na serwerze. Sygnalizujący, że wszystkie instalacje z klientem do serwera są obsługiwane.

Sygnalizujący oferuje również interfejs API niższego poziomu o nazwie połączeń trwałych. Aby zapoznać się z wprowadzeniem do sygnałów, centrów i połączeń trwałych, zobacz wprowadzenie do sygnalizującego 2.

Wersje oprogramowania używane w tym temacie

Wersje tematów

Aby uzyskać informacje o wcześniejszych wersjach programu sygnalizującego, zobacz sekcję sygnalizujące starsze wersje.

Pytania i Komentarze

Prosimy o opinię na temat sposobu, w jaki lubię ten samouczek, i co możemy ulepszyć w komentarzach w dolnej części strony. Jeśli masz pytania, które nie są bezpośrednio związane z samouczkiem, możesz je ogłosić na forum ASP.NET lub StackOverflow.com.

Omówienie

Ten dokument zawiera następujące sekcje:

Aby uzyskać dokumentację dotyczącą sposobu programowania klientów, zobacz następujące zasoby:

Składniki serwera dla sygnalizującego 2 są dostępne tylko w programie .NET 4,5. Na serwerach z programem .NET 4,0 musi być używany program sygnalizujący v1. x.

Jak zarejestrować oprogramowanie pośredniczące sygnalizujące

Aby zdefiniować trasę, która będzie używana przez klientów do łączenia się z centrum, należy wywołać MapSignalR metodę podczas uruchamiania aplikacji. MapSignalR jest metodą rozszerzającą dla OwinExtensions klasy. Poniższy przykład pokazuje, jak zdefiniować trasę centrów sygnałów przy użyciu klasy startowej OWIN.

using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(MyApplication.Startup))]
namespace MyApplication
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();
        }

    }
}

Jeśli dodajesz funkcję sygnalizującą do aplikacji ASP.NET MVC, upewnij się, że trasa sygnalizująca jest dodawana przed innymi trasami. Aby uzyskać więcej informacji, zobacz Samouczek: wprowadzenie z sygnałami 2 i MVC 5.

Adres URL/SignalR

Domyślnie adres URL trasy używany przez klientów do łączenia się z centrum to "/SignalR". (Nie należy mylić tego adresu URL z adresem URL "/SignalR/Hubs", który jest przeznaczony dla automatycznie generowanego pliku języka JavaScript. Aby uzyskać więcej informacji na temat wygenerowanego serwera proxy, zobacz Przewodnik interfejsu API centrów sygnałów — klient JavaScript — wygenerowany serwer proxy i jego zawartość.

Mogą występować nadzwyczajne sytuacje, w których ten podstawowy adres URL nie może być użyteczny dla sygnalizującego; na przykład w projekcie znajduje się folder o nazwie sygnalizujący i nie chcesz zmieniać nazwy. W takim przypadku można zmienić podstawowy adres URL, jak pokazano w poniższych przykładach (Zastąp "/SignalR" w przykładowym kodzie z żądanym adresem URL).

Kod serwera, który określa adres URL

app.MapSignalR("/signalr", new HubConfiguration());

Kod klienta JavaScript, który określa adres URL (z wygenerowanym serwerem proxy)

$.connection.hub.url = "/signalr"
$.connection.hub.start().done(init);

Kod klienta JavaScript, który określa adres URL (bez wygenerowanego serwera proxy)

var connection = $.hubConnection("/signalr", { useDefaultPath: false });

Kod klienta .NET, który określa adres URL

var hubConnection = new HubConnection("http://contoso.com/signalr", useDefaultUrl: false);

Konfigurowanie opcji sygnalizujących

Przeciążenia MapSignalR metody umożliwiają określenie niestandardowego adresu URL, niestandardowego programu rozpoznawania zależności i następujących opcji:

  • Włącz wywołania międzydomenowe za pomocą mechanizmu CORS lub JSONP z klientów przeglądarek.

    Zazwyczaj Jeśli przeglądarka ładuje stronę z http://contoso.com , połączenie sygnalizujące znajduje się w tej samej domenie, w http://contoso.com/signalr . Jeśli strona z programu http://contoso.com nawiązuje połączenie z http://fabrikam.com/signalr , jest to połączenie między domenami. Ze względów bezpieczeństwa połączenia między domenami są domyślnie wyłączone. Aby uzyskać więcej informacji, zobacz Przewodnik dotyczący interfejsu API centrów ASP.NET Signals — JavaScript Client — jak ustanowić połączenie między domenami.

  • Włącz szczegółowe komunikaty o błędach.

    Gdy wystąpią błędy, domyślne zachowanie sygnalizującego jest wysyłane do klientów komunikat powiadomienia bez szczegółowych informacji o tym, co się stało. Wysyłanie szczegółowych informacji o błędach do klientów nie jest zalecane w środowisku produkcyjnym, ponieważ Złośliwi użytkownicy mogą korzystać z informacji w przypadku ataków na aplikację. W przypadku rozwiązywania problemów można użyć tej opcji, aby tymczasowo włączyć bardziej informacyjne raportowanie błędów.

  • Wyłącz automatycznie generowane pliki proxy JavaScript.

    Domyślnie plik JavaScript z serwerami proxy dla klas centrów jest generowany w odpowiedzi na adres URL "/SignalR/Hubs". Jeśli nie chcesz używać serwerów proxy języka JavaScript lub chcesz wygenerować ten plik ręcznie i zapoznaj się z plikiem fizycznym na klientach, możesz użyć tej opcji, aby wyłączyć generowanie serwera proxy. Aby uzyskać więcej informacji, zobacz Przewodnik interfejsu API centrów sygnałów — JavaScript Client — jak utworzyć plik fizyczny dla generowanego przez program sygnalizującego serwera proxy.

Poniższy przykład pokazuje, jak określić adres URL połączenia sygnalizującego i te opcje w wywołaniu MapSignalR metody. Aby określić niestandardowy adres URL, Zastąp ciąg "/SignalR" w przykładzie adresem URL, którego chcesz użyć.

var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableDetailedErrors = true;
hubConfiguration.EnableJavaScriptProxies = false;
app.MapSignalR("/signalr", hubConfiguration);

Tworzenie i używanie klas centrów

Aby utworzyć centrum, należy utworzyć klasę, która pochodzi od elementu Microsoft. ASPNET. signaler. Hub. W poniższym przykładzie przedstawiono prostą klasę centrów dla aplikacji czatu.

public class ContosoChatHub : Hub
{
    public async Task NewContosoChatMessage(string name, string message)
    {
        await Clients.All.addNewMessageToPage(name, message);
    }
}

W tym przykładzie połączony klient może wywoływać NewContosoChatMessage metodę, a gdy tak, otrzymane dane są rozgłaszane do wszystkich połączonych klientów.

Okres istnienia obiektu centrum

Nie można utworzyć wystąpienia klasy centrum ani wywołać jej metod z własnego kodu na serwerze; wszystko to wykonywane przez potok centrów sygnałów. Program sygnalizujący tworzy nowe wystąpienie klasy centrów za każdym razem, gdy musi obsłużyć operację centrum, taką jak gdy klient łączy się, rozłącza lub wywołuje metodę wywołania do serwera.

Ponieważ wystąpienia klasy centrów są przejściowe, nie można ich używać do utrzymania stanu z jednego wywołania metody do następnego. Za każdym razem, gdy serwer odbiera wywołanie metody z klienta, nowe wystąpienie klasy Hub przetwarza komunikat. Aby zachować stan za pośrednictwem wielu połączeń i wywołań metod, należy użyć innej metody, takiej jak baza danych lub zmienna statyczna w klasie Hub lub innej klasy, która nie pochodzi od Hub . W przypadku utrwalania danych w pamięci przy użyciu metody takiej jak zmienna statyczna w klasie centrów dane zostaną utracone podczas odtwarzania domeny aplikacji.

Jeśli chcesz wysyłać komunikaty do klientów z własnego kodu, który jest uruchamiany poza klasą Hub, nie można tego zrobić przez utworzenie wystąpienia klasy centrum, ale można to zrobić, pobierając odwołanie do obiektu kontekstu sygnalizującego dla klasy centrum. Aby uzyskać więcej informacji, zobacz jak wywoływać metody klienta i zarządzać grupami spoza klasy Hub w dalszej części tego tematu.

Notacji CamelCase — wielkość liter w nazwach centrów w klientach JavaScript

Domyślnie klienci języka JavaScript odwołują się do centrów przy użyciu notacji camelcaseej wersji klasy. Program sygnalizujący automatycznie wprowadza tę zmianę, aby kod JavaScript mógł być zgodny z konwencjami języka JavaScript. Poprzedni przykład zostałby określony jako contosoChatHub kod JavaScript.

Server (Serwer)

public class ContosoChatHub : Hub

Klient JavaScript korzystający z wygenerowanego serwera proxy

var contosoChatHubProxy = $.connection.contosoChatHub;

Jeśli chcesz określić inną nazwę do użycia przez klientów, Dodaj HubName atrybut. W przypadku użycia HubName atrybutu nie jest zmieniana nazwa notacji CamelCase przypadku na klientach JavaScript.

Server (Serwer)

[HubName("PascalCaseContosoChatHub")]
public class ContosoChatHub : Hub

Klient JavaScript korzystający z wygenerowanego serwera proxy

var contosoChatHubProxy = $.connection.PascalCaseContosoChatHub;

Wiele centrów

W aplikacji można definiować wiele klas centrów. Po wykonaniu tej czynności połączenie jest udostępniane, ale grupy są osobne:

  • Wszyscy klienci będą używać tego samego adresu URL, aby nawiązać połączenie sygnalizujące z usługą ("/SignalR" lub niestandardowy adres URL, jeśli został określony) i że połączenie jest używane dla wszystkich centrów zdefiniowanych przez usługę.

    Nie ma różnicy wydajności dla wielu centrów w porównaniu do definiowania wszystkich funkcji centrum w jednej klasie.

  • Wszystkie centra uzyskują te same informacje o żądaniu HTTP.

    Ponieważ wszystkie centra korzystają z tego samego połączenia, jedyną informacją o żądaniu HTTP, którą pobiera serwer, jest to, co znajduje się w oryginalnym żądaniu HTTP, które nawiązuje połączenie sygnalizujące. W przypadku użycia żądania połączenia w celu przekazania informacji z klienta do serwera przez określenie ciągu zapytania nie można podać różnych parametrów zapytania do różnych centrów. Wszystkie centra będą otrzymywać te same informacje.

  • Wygenerowany plik proxy języka JavaScript będzie zawierać serwery proxy dla wszystkich centrów w jednym pliku.

    Aby uzyskać informacje na temat serwerów proxy języka JavaScript, zobacz Przewodnik interfejsu API centrów sygnałów-JavaScript Client-wygenerowany serwer proxy i jego zawartość.

  • Grupy są zdefiniowane w centrach.

    W programie Sygnalizującer można zdefiniować nazwane grupy do emisji do podzestawów połączonych klientów. Grupy są utrzymywane osobno dla każdego centrum. Na przykład grupa o nazwie "Administratorzy" będzie zawierać jeden zestaw klientów dla ContosoChatHub klasy, a ta sama nazwa grupy będzie odwoływać się do innego zestawu klientów dla StockTickerHub klasy.

Centra Strongly-Typed

Aby zdefiniować interfejs dla metod centrów, do których Twój klient może się odwoływać (i włączyć funkcję IntelliSense w metodach centrum), należy utworzyć koncentrator od Hub<T> (wprowadzonego w sygnalizacji 2,1), a nie Hub :

public class StrongHub : Hub<IClient>
{
    public async Task Send(string message)
    {
        await Clients.All.NewMessage(message);
    }
}

public interface IClient
{
    Task NewMessage(string message);
}

Jak zdefiniować metody w klasie centrów, które mogą być wywoływane przez klientów

Aby uwidocznić metodę w centrum, która ma być wywoływana z klienta, zadeklaruj metodę publiczną, jak pokazano w poniższych przykładach.

public class ContosoChatHub : Hub
{
    public async Task NewContosoChatMessage(string name, string message)
    {
        await Clients.All.addNewMessageToPage(name, message);
    }
}
public class StockTickerHub : Hub
{
    public IEnumerable<Stock> GetAllStocks()
    {
        return _stockTicker.GetAllStocks();
    }
}

Można określić typ zwracany i parametry, w tym typy złożone i tablice, tak jak w przypadku dowolnej metody języka C#. Wszystkie dane, które są odbierane w parametrach lub zwracane do obiektu wywołującego, są przekazywane między klientem a serwerem przy użyciu JSON, a sygnalizujący obsługuje powiązanie obiektów złożonych i tablic obiektów automatycznie.

Notacji CamelCase — wielkość liter w nazwach metod w klientach JavaScript

Domyślnie klienci języka JavaScript odwołują się do metod centrów przy użyciu notacji camelcaseej wersji metody. Program sygnalizujący automatycznie wprowadza tę zmianę, aby kod JavaScript mógł być zgodny z konwencjami języka JavaScript.

Server (Serwer)

public void NewContosoChatMessage(string userName, string message)

Klient JavaScript korzystający z wygenerowanego serwera proxy

contosoChatHubProxy.server.newContosoChatMessage(userName, message);

Jeśli chcesz określić inną nazwę do użycia przez klientów, Dodaj HubMethodName atrybut.

Server (Serwer)

[HubMethodName("PascalCaseNewContosoChatMessage")]
public void NewContosoChatMessage(string userName, string message)

Klient JavaScript korzystający z wygenerowanego serwera proxy

contosoChatHubProxy.server.PascalCaseNewContosoChatMessage(userName, message);

Kiedy wykonać asynchronicznie

Jeśli metoda będzie długotrwała lub musi wykonywać zadania, które mogą być zależne, takie jak wyszukiwanie bazy danych lub wywołanie usługi sieci Web, ustaw metodę Hub jako asynchroniczną, zwracając zadanie (w miejscu void powrotu) lub obiekt < T > zadania (zamiast T typu zwracanego). Gdy zwracasz Task obiekt z metody, sygnalizujący czeka na Task zakończenie, a następnie wysyła nieopakowany wynik z powrotem do klienta, więc nie ma żadnych różnic w sposobie kodowania wywołania metody na kliencie.

Stosowanie metody centrum asynchronicznie zapobiega blokowaniu połączenia w przypadku korzystania z transportu WebSocket. Gdy metoda centrum jest wykonywana synchronicznie, a transport jest w trybie WebSocket, kolejne wywołania metod znajdujących się w koncentratorze z tego samego klienta są blokowane do momentu zakończenia metody centrum.

Poniższy przykład pokazuje tę samą metodę, która jest zakodowana do uruchamiania synchronicznie lub asynchronicznie, po którym następuje kod klienta JavaScript, który działa w przypadku wywoływania jednej wersji.

Synchronous

public IEnumerable<Stock> GetAllStocks()
{
    // Returns data from memory.
    return _stockTicker.GetAllStocks();
}

Asynchroniczny

public async Task<IEnumerable<Stock>> GetAllStocks()
{
    // Returns data from a web service.
    var uri = Util.getServiceUri("Stocks");
    using (HttpClient httpClient = new HttpClient())
    {
        var response = await httpClient.GetAsync(uri);
        return (await response.Content.ReadAsAsync<IEnumerable<Stock>>());
    }
}

Klient JavaScript korzystający z wygenerowanego serwera proxy

stockTickerHubProxy.server.getAllStocks().done(function (stocks) {
    $.each(stocks, function () {
        alert(this.Symbol + ' ' + this.Price);
    });
});

Aby uzyskać więcej informacji o sposobach używania metod asynchronicznych w ASP.NET 4,5, zobacz Używanie metod asynchronicznych w ASP.NET MVC 4.

Definiowanie przeciążeń

Jeśli chcesz zdefiniować przeciążenia dla metody, liczba parametrów w każdym przeciążeniu musi się różnić. W przypadku odróżnienia przeciążenia po określeniu różnych typów parametrów, Klasa centrum zostanie skompilowana, ale usługa sygnalizująca zgłosi wyjątek w czasie wykonywania, gdy klienci spróbują wywołać jedno z przeciążeń.

Raportowanie postępu z wywołań metod centrów

Sygnał 2,1 dodaje obsługę wzorca raportowania postępu wprowadzonego w programie .NET 4,5. Aby zaimplementować Raportowanie postępu, zdefiniuj IProgress<T> parametr dla metody centrum, do której Twój klient ma dostęp:

public class ProgressHub : Hub
{
    public async Task<string> DoLongRunningThing(IProgress<int> progress)
    {
        for (int i = 0; i <= 100; i+=5)
        {
            await Task.Delay(200);
            progress.Report(i);
        }
        return "Job complete!";
    }
}

Podczas pisania długotrwałej metody serwera należy użyć asynchronicznego wzorca programowania, takiego jak Async/await, zamiast blokować wątek centrum.

Jak wywołać metody klienta z klasy Hub

Aby wywołać metody klienta z serwera, użyj Clients właściwości w metodzie klasy Hub. Poniższy przykład przedstawia kod serwera, który wywołuje addNewMessageToPage wszystkie połączone klienckie i kod klienta, który definiuje metodę w kliencie JavaScript.

Server (Serwer)

public class ContosoChatHub : Hub
{
    public async Task NewContosoChatMessage(string name, string message)
    {
        await Clients.All.addNewMessageToPage(name, message);
    }
}

Wywołanie metody klienta jest operacją asynchroniczną i zwraca wartość Task . Użyj await :

  • , Aby upewnić się, że komunikat jest wysyłany bez błędu.
  • Aby włączyć przechwytywanie i obsłużyć błędy w bloku try-catch.

Klient JavaScript korzystający z wygenerowanego serwera proxy

contosoChatHubProxy.client.addNewMessageToPage = function (name, message) {
    // Add the message to the page. 
    $('#discussion').append('<li><strong>' + htmlEncode(name)
        + '</strong>: ' + htmlEncode(message) + '<li>');
};

Nie można uzyskać wartości zwracanej z metody klienta; Składnia, taka jak nie int x = Clients.All.add(1,1) działa.

Można określić typy złożone i tablice dla parametrów. Poniższy przykład przekazuje typ złożony do klienta w parametrze metody.

Kod serwera, który wywołuje metodę klienta przy użyciu obiektu złożonego

public async Task SendMessage(string name, string message)
{
    await Clients.All.addContosoChatMessageToPage(new ContosoChatMessage() { UserName = name, Message = message });
}

Kod serwera, który definiuje obiekt złożony

public class ContosoChatMessage
{
    public string UserName { get; set; }
    public string Message { get; set; }
}

Klient JavaScript korzystający z wygenerowanego serwera proxy

var contosoChatHubProxy = $.connection.contosoChatHub;
contosoChatHubProxy.client.addMessageToPage = function (message) {
    console.log(message.UserName + ' ' + message.Message);
});

Wybieranie klientów, którzy będą otrzymywać wywołania RPC

Właściwość klienci zwraca obiekt HubConnectionContext , który udostępnia kilka opcji określania klientów, którzy będą otrzymywać wywołania RPC:

  • Wszyscy połączeni klienci.

    Clients.All.addContosoChatMessageToPage(name, message);
    
  • Tylko klient wywołujący.

    Clients.Caller.addContosoChatMessageToPage(name, message);
    
  • Wszyscy klienci z wyjątkiem klienta wywołującego.

    Clients.Others.addContosoChatMessageToPage(name, message);
    
  • Określony klient identyfikowany przez identyfikator połączenia.

    Clients.Client(Context.ConnectionId).addContosoChatMessageToPage(name, message);
    

    Ten przykład wywołuje addContosoChatMessageToPage klienta wywołującego i ma ten sam skutek jak użycie Clients.Caller .

  • Wszyscy połączeni klienci z wyjątkiem określonych klientów identyfikowane przez identyfikator połączenia.

    Clients.AllExcept(connectionId1, connectionId2).addContosoChatMessageToPage(name, message);
    
  • Wszyscy połączeni klienci w określonej grupie.

    Clients.Group(groupName).addContosoChatMessageToPage(name, message);
    
  • Wszyscy połączeni klienci w określonej grupie z wyjątkiem określonych klientów identyfikowane przez identyfikator połączenia.

    Clients.Group(groupName, connectionId1, connectionId2).addContosoChatMessageToPage(name, message);
    
  • Wszyscy połączeni klienci w określonej grupie z wyjątkiem klienta wywołującego.

    Clients.OthersInGroup(groupName).addContosoChatMessageToPage(name, message);
    
  • Określony użytkownik identyfikowany według identyfikatora użytkownika.

    Clients.User(userid).addContosoChatMessageToPage(name, message);
    

    Domyślnie jest to IPrincipal.Identity.Name możliwe, ale można to zmienić, rejestrując implementację IUserIdProvider z hostem globalnym.

  • Wszyscy klienci i grupy na liście identyfikatorów połączeń.

    Clients.Clients(ConnectionIds).broadcastMessage(name, message);
    
  • Lista grup.

    Clients.Groups(GroupIds).broadcastMessage(name, message);
    
  • Użytkownik według nazwy.

    Clients.Client(username).broadcastMessage(name, message);
    
  • Lista nazw użytkowników (wprowadzona w sygnalizacji 2,1).

    Clients.Users(new string[] { "myUser", "myUser2" }).broadcastMessage(name, message);
    

Brak weryfikacji w czasie kompilacji dla nazw metod

Określona nazwa metody jest interpretowana jako obiekt dynamiczny, co oznacza, że nie istnieje funkcja IntelliSense ani weryfikacja w czasie kompilacji. Wyrażenie jest oceniane w czasie wykonywania. Gdy wywołanie metody jest wykonywane, sygnalizujący wysyła nazwę metody i wartości parametrów do klienta, a jeśli klient ma metodę zgodną z nazwą, ta metoda jest wywoływana i są do niej przenoszone wartości parametrów. Jeśli na kliencie nie zostanie znaleziona zgodna Metoda, żaden błąd nie zostanie zgłoszony. Aby uzyskać informacje na temat formatu danych przesyłanych do klienta przez program sygnalizujący w tle podczas wywoływania metody klienta, zobacz wprowadzenie do usługi sygnalizującej.

Dopasowanie nazw metod bez uwzględniania wielkości liter

W dopasowaniu nazw metod nie jest rozróżniana wielkość liter. Na przykład Clients.All.addContosoChatMessageToPage na serwerze zostanie uruchomiony AddContosoChatMessageToPage program, addcontosochatmessagetopage lub addContosoChatMessageToPage na kliencie.

Wykonywanie asynchroniczne

Wywoływana metoda jest wykonywana asynchronicznie. Każdy kod, który jest wywoływany po wywołaniu metody do klienta, będzie wykonywany natychmiast bez oczekiwania na zakończenie przesyłania danych do klientów przez program sygnalizujący, chyba że określisz, że kolejne wiersze kodu powinny czekać na ukończenie metody. Poniższy przykład kodu pokazuje, jak wykonać dwie metody klienta sekwencyjnie.

Używanie oczekiwania (.NET 4,5)

public async Task NewContosoChatMessage(string name, string message)
{
    await Clients.Others.addContosoChatMessageToPage(data);
    await Clients.Caller.notifyMessageSent();
}

Jeśli używasz await , aby poczekać do momentu zakończenia metody klienta przed wykonaniem kolejnego wiersza kodu, który nie oznacza, że klienci otrzymają komunikat przed wykonaniem kolejnego wiersza kodu. "Uzupełnianie" wywołania metody klienta oznacza tylko, że sygnalizujący zrobił wszystko niezbędne do wysłania wiadomości. Jeśli potrzebujesz weryfikacji, że klienci otrzymali komunikat, musisz samodzielnie programować ten mechanizm. Można na przykład zakodować MessageReceived metodę w centrum i addContosoChatMessageToPage metodę na kliencie, którą można wywołać po wykonaniu MessageReceived dowolnej pracy, którą trzeba wykonać na kliencie. W MessageReceived programie w centrum można wykonać dowolną czynność, która zależy od rzeczywistego odbioru klienta i przetwarzania oryginalnego wywołania metody.

Jak używać zmiennej ciągu jako nazwy metody

Jeśli chcesz wywołać metodę klienta przy użyciu zmiennej ciągu jako nazwę metody, Cast Clients.All (lub Clients.Others , Clients.Caller itp.), IClientProxy a następnie wywołać Invoke (MethodName, args...).

public async Task NewContosoChatMessage(string name, string message)
{
    string methodToCall = "addContosoChatMessageToPage";
    IClientProxy proxy = Clients.All;
    await proxy.Invoke(methodToCall, name, message);
}

Zarządzanie członkostwem w grupie z klasy centrów

Grupy w sygnalizacji zapewniają metodę rozgłaszania komunikatów do określonych podzestawów połączonych klientów. Grupa może mieć dowolną liczbę klientów, a klient może być członkiem dowolnej liczby grup.

Aby zarządzać członkostwem w grupie, użyj metod Add i Remove dostarczonych przez Groups Właściwość klasy Hub. Poniższy przykład pokazuje Groups.Add Groups.Remove metody i stosowane w metodach centralnych wywoływanych przez kod klienta, po których następuje kod klienta JavaScript, który wywołuje je.

Server (Serwer)

public class ContosoChatHub : Hub
{
    public Task JoinGroup(string groupName)
    {
        return Groups.Add(Context.ConnectionId, groupName);
    }

    public Task LeaveGroup(string groupName)
    {
        return Groups.Remove(Context.ConnectionId, groupName);
    }
}

Klient JavaScript korzystający z wygenerowanego serwera proxy

contosoChatHubProxy.server.joinGroup(groupName);
contosoChatHubProxy.server.leaveGroup(groupName);

Nie musisz jawnie tworzyć grup. W efekcie Grupa jest tworzona automatycznie przy pierwszym określeniu jej nazwy w wywołaniu do Groups.Add i zostanie usunięta po usunięciu ostatniego połączenia z członkostwa w nim.

Brak interfejsu API do uzyskiwania listy członkostwa w grupie lub listy grup. Program sygnalizujący wysyła komunikaty do klientów i grup na podstawie modelu pub/sub, a serwer nie zachowuje list grup ani członkostw w grupach. Pozwala to zmaksymalizować skalowalność, ponieważ po dodaniu węzła do kolektywu serwerów sieci Web, każdy stan, który utrzymuje usługa sygnalizująca, musi być propagowany do nowego węzła.

Asynchroniczne wykonywanie metod Add i Remove

Groups.AddMetody i są Groups.Remove wykonywane asynchronicznie. Jeśli chcesz dodać klienta do grupy i natychmiast wysłać komunikat do klienta przy użyciu grupy, musisz upewnić się, że Groups.Add Metoda zakończy się najpierw. Poniższy przykład kodu pokazuje, jak to zrobić.

Dodawanie klienta do grupy, a następnie wysyłanie komunikatów do klienta

public async Task JoinGroup(string groupName)
{
    await Groups.Add(Context.ConnectionId, groupName);
    await Clients.Group(groupname).addContosoChatMessageToPage(Context.ConnectionId + " added to group");
}

Trwałość członkostwa w grupie

Program sygnalizujący śledzi połączenia, a nie użytkowników, dlatego jeśli chcesz, aby użytkownik znajdował się w tej samej grupie za każdym razem, gdy użytkownik nawiąże połączenie, należy wywołać za każdym razem, gdy użytkownik Groups.Add ustanowi nowe połączenie.

Po tymczasowej utracie łączności czasami program sygnalizujący może automatycznie przywrócić połączenie. W takim przypadku sygnalizujący przywraca to samo połączenie, nie ustanawia nowego połączenia, a więc członkostwo w grupie klienta zostanie automatycznie przywrócone. Jest to możliwe nawet wtedy, gdy tymczasowy przerwanie jest wynikiem ponownego uruchomienia serwera lub błędu, ponieważ stan połączenia dla każdego klienta, w tym członkostwa w grupie, jest przełączany do klienta. Jeśli serwer ulegnie awarii i zostanie zastąpiony przez nowy serwer przed przekroczeniem limitu czasu, klient będzie mógł automatycznie połączyć się z nowym serwerem i ponownie zarejestrować w grupach, które jest członkiem.

Gdy połączenie nie może zostać przywrócone automatycznie po utracie łączności lub gdy upłynął limit czasu połączenia lub gdy klient odłączy się (na przykład gdy przeglądarka nawiguje do nowej strony), członkostwo w grupach zostanie utracone. Następnym razem, gdy użytkownik łączy się z nowym połączeniem. Aby zachować członkostwo w grupach, gdy ten sam użytkownik ustanowi nowe połączenie, aplikacja musi śledzić skojarzenia między użytkownikami i grupami oraz przywracać członkostwa w grupach za każdym razem, gdy użytkownik ustanowi nowe połączenie.

Więcej informacji o połączeniach i repołączeniach znajduje się w temacie jak obsłużyć zdarzenia okresu istnienia połączenia w klasie centrów w dalszej części tego tematu.

Grupy pojedynczego użytkownika

Aplikacje korzystające z programu sygnalizującego zwykle muszą śledzić skojarzenia między użytkownikami i połączeniami, aby wiedzieć, który użytkownik wysłał komunikat i które użytkownicy powinni otrzymywać wiadomości. Grupy są używane w jednym z dwóch często używanych wzorców w celu wykonania tej operacji.

  • Grupy pojedynczego użytkownika.

    Możesz określić nazwę użytkownika jako nazwę grupy i dodać bieżący identyfikator połączenia do grupy za każdym razem, gdy użytkownik łączy się lub ponownie nawiązuje połączenie. Wysyłanie komunikatów do użytkownika, który jest wysyłany do grupy. Wadą tej metody jest to, że grupa nie pozwala na ustalenie, czy użytkownik jest w trybie online, czy offline.

  • Śledź skojarzenia między nazwami użytkowników i identyfikatorami połączeń.

    Można przechowywać skojarzenie między nazwami użytkowników i co najmniej jednym identyfikatorem połączenia w słowniku lub bazie danych i aktualizować przechowywane dane za każdym razem, gdy użytkownik nawiązuje połączenie lub rozłącza. Aby wysyłać komunikaty do użytkownika, należy określić identyfikatory połączeń. Wadą tej metody jest to, że zajmuje więcej pamięci.

Jak obsłużyć zdarzenia okresu istnienia połączenia w klasie centrów

Typowymi przyczynami obsługi zdarzeń okresu istnienia połączenia są śledzenie tego, czy użytkownik jest połączony, i śledzenie skojarzenia między nazwami użytkowników i identyfikatorami połączeń. Aby uruchomić własny kod, gdy klienci nawiązują połączenie lub rozłącza, Zastąp OnConnected OnDisconnected metody, i OnReconnected wirtualne klasy Hub, jak pokazano w poniższym przykładzie.

public class ContosoChatHub : Hub
{
    public override Task OnConnected()
    {
        // Add your own code here.
        // For example: in a chat application, record the association between
        // the current connection ID and user name, and mark the user as online.
        // After the code in this method completes, the client is informed that
        // the connection is established; for example, in a JavaScript client,
        // the start().done callback is executed.
        return base.OnConnected();
    }

    public override Task OnDisconnected(bool stopCalled)
    {
        // Add your own code here.
        // For example: in a chat application, mark the user as offline, 
        // delete the association between the current connection id and user name.
        return base.OnDisconnected(stopCalled);
    }

    public override Task OnReconnected()
    {
        // Add your own code here.
        // For example: in a chat application, you might have marked the
        // user as offline after a period of inactivity; in that case 
        // mark the user as online again.
        return base.OnReconnected();
    }
}

Gdy są wywoływane metody OnConnected, ondisconnected i OnReconnected

Za każdym razem, gdy przeglądarka nawiguje do nowej strony, należy nawiązać nowe połączenie, co oznacza, że sygnał wykona OnDisconnected metodę OnConnected . Sygnalizujący zawsze tworzy nowy identyfikator połączenia po nawiązaniu nowego połączenia.

OnReconnectedMetoda jest wywoływana, gdy nastąpiło tymczasowe przerwanie łączności, z której sygnalizujący mogą automatycznie odzyskiwać dane, na przykład gdy kabel jest tymczasowo odłączony i ponownie połączony przed upływem limitu czasu połączenia. OnDisconnectedMetoda jest wywoływana, gdy klient zostanie odłączony, a sygnalizujący nie może automatycznie ponownie nawiązać połączenia, na przykład gdy przeglądarka nawiguje do nowej strony. W związku z tym, możliwa sekwencja zdarzeń dla danego klienta to OnConnected , OnReconnected , OnDisconnected ; lub OnConnected , OnDisconnected . Nie zobaczysz sekwencji OnConnected OnDisconnected OnReconnected dla danego połączenia.

OnDisconnectedMetoda nie jest wywoływana w niektórych scenariuszach, na przykład w przypadku awarii serwera lub odtworzenia domeny aplikacji. Gdy inny serwer jest w trybie online lub domena aplikacji zakończy jego odtwarzanie, niektórzy klienci mogą być w stanie ponownie nawiązać połączenie i uruchomić OnReconnected zdarzenie.

Aby uzyskać więcej informacji, zobacz Omówienie i obsługa zdarzeń okresu istnienia połączenia w programie sygnalizującym.

Stan wywołującego nie został wypełniony

Metody obsługi zdarzeń okresu istnienia połączenia są wywoływane z serwera, co oznacza, że każdy stan umieszczony w state obiekcie na kliencie nie zostanie wypełniony we Caller właściwości na serwerze. Aby uzyskać informacje na temat state obiektu i Caller właściwości, zobacz jak przekazać stan między klientami a klasą centrum w dalszej części tego tematu.

Jak uzyskać informacje o kliencie z właściwości kontekstu

Aby uzyskać informacje o kliencie, należy użyć Context właściwości klasy centrum. ContextWłaściwość zwraca obiekt HubCallerContext , który zapewnia dostęp do następujących informacji:

  • Identyfikator połączenia klienta wywołującego.

    string connectionID = Context.ConnectionId;
    

    Identyfikator połączenia jest identyfikatorem GUID, który jest przypisany przez sygnalizujący (nie można określić wartości w własnym kodzie). Istnieje jeden identyfikator połączenia dla każdego połączenia, a ten sam identyfikator połączenia jest używany przez wszystkie centra, jeśli w aplikacji znajduje się wiele centrów.

  • Dane nagłówka HTTP.

    System.Collections.Specialized.NameValueCollection headers = Context.Request.Headers;
    

    Można również uzyskać nagłówki HTTP z Context.Headers . Przyczyną wielu odwołań do tego samego elementu jest, który Context.Headers został utworzony jako pierwszy, Context.Request Właściwość została dodana później i Context.Headers została zachowana w celu zapewnienia zgodności z poprzednimi wersjami.

  • Dane ciągu zapytania.

    System.Collections.Specialized.NameValueCollection queryString = Context.Request.QueryString;
    string parameterValue = queryString["parametername"]
    

    Możesz również uzyskać dane ciągu zapytania z Context.QueryString .

    Ciąg zapytania, który jest pobierany w tej właściwości, jest używany z żądaniem HTTP, które ustanowiło połączenie sygnalizujące. Parametry ciągu zapytania można dodać do klienta przez skonfigurowanie połączenia, które jest wygodnym sposobem przekazywania danych dotyczących klienta z klienta do serwera programu. W poniższym przykładzie pokazano jeden ze sposobów dodawania ciągu zapytania do klienta JavaScript w przypadku korzystania z wygenerowanego serwera proxy.

    $.connection.hub.qs = { "version" : "1.0" };
    

    Aby uzyskać więcej informacji na temat ustawiania parametrów ciągu zapytania, zobacz Przewodniki interfejsu API dla klientów JavaScript i .NET .

    Metodę transportu używaną w połączeniu można znaleźć w danych ciągu zapytania, wraz z innymi wartościami używanymi wewnętrznie przez program sygnalizujący:

    string transportMethod = queryString["transport"];
    

    Wartość będzie równa transportMethod "WebSockets", "serverSentEvents", "foreverFrame" lub "longPolling". Należy pamiętać, że jeśli ta wartość zostanie sprawdzona w OnConnected metodzie obsługi zdarzeń, w niektórych scenariuszach można początkowo uzyskać wartość transportu, która nie jest ostateczną negocjowaną metodą transportu dla połączenia. W takim przypadku Metoda zgłosi wyjątek i zostanie wywołana ponownie później podczas ustanowienia końcowej metody transportu.

  • Cookie.

    System.Collections.Generic.IDictionary<string, Cookie> cookies = Context.Request.Cookies;
    

    Możesz również pobrać pliki cookie z programu Context.RequestCookies .

  • Informacje o użytkowniku.

    System.Security.Principal.IPrincipal user = Context.User;
    
  • Obiekt HttpContext dla żądania:

    System.Web.HttpContextBase httpContext = Context.Request.GetHttpContext();
    

    Użyj tej metody zamiast HttpContext.Current pobierać HttpContext obiekt dla połączenia sygnalizującego.

Jak przekazać stan między klientami a klasą centrum

Serwer proxy klienta udostępnia state obiekt, w którym można przechowywać dane, które mają być przesyłane do serwera przy użyciu każdego wywołania metody. Na serwerze możesz uzyskać dostęp do tych danych we Clients.Caller właściwości w metodach centralnych wywoływanych przez klientów. Clients.CallerWłaściwość nie jest wypełniona dla metod obsługi zdarzeń okresu istnienia połączenia OnConnected , OnDisconnected i OnReconnected .

Tworzenie lub aktualizowanie danych w state obiekcie i Clients.Caller Właściwość działa w obu kierunkach. Można aktualizować wartości na serwerze i są one przesyłane z powrotem do klienta programu.

Poniższy przykład przedstawia kod klienta JavaScript, który przechowuje stan przesyłania do serwera przy każdym wywołaniu metody.

contosoChatHubProxy.state.userName = "Fadi Fakhouri";
contosoChatHubProxy.state.computerName = "fadivm1";

Poniższy przykład pokazuje odpowiedni kod w kliencie .NET.

contosoChatHubProxy["userName"] = "Fadi Fakhouri";
chatHubProxy["computerName"] = "fadivm1";

W klasie centrów możesz uzyskać dostęp do tych danych we Clients.Caller właściwości. Poniższy przykład pokazuje kod, który pobiera stan, do którego odwołuje się w poprzednim przykładzie.

public async Task NewContosoChatMessage(string data)
{
    string userName = Clients.Caller.userName;
    string computerName = Clients.Caller.computerName;
    await Clients.Others.addContosoChatMessageToPage(message, userName, computerName);
}

Note

Ten mechanizm dla stanu utrwalania nie jest przeznaczony dla dużych ilości danych, ponieważ wszystko, co zostało umieszczone w state lub Clients.Caller Właściwość jest wyłączane, z każdym wywołaniem metody. Jest to przydatne w przypadku mniejszych elementów, takich jak nazwy użytkowników lub liczniki.

W VB.NET lub w koncentratorze o jednoznacznie określonym typie nie można uzyskać dostępu do obiektu stanu wywołującego za pomocą Clients.Caller ; zamiast tego należy użyć Clients.CallerState (wprowadzona w sygnalizacji 2,1):

Korzystanie z CallerState w języku C #

public async Task NewContosoChatMessage(string data)
{
    string userName = Clients.CallerState.userName;
    string computerName = Clients.CallerState.computerName;
    await Clients.Others.addContosoChatMessageToPage(data, userName, computerName);
}

Używanie CallerState w Visual Basic

Public Async Function NewContosoChatMessage(message As String) As Task
    Dim userName As String = Clients.CallerState.userName
    Dim computerName As String = Clients.CallerState.computerName
    Await Clients.Others.addContosoChatMessageToPage(message, userName, computerName)
End Sub

Jak obsłużyć błędy w klasie centrów

Aby obsłużyć błędy występujące w metodach klasy centrum, należy najpierw upewnić się, że wszystkie wyjątki od operacji asynchronicznych (takich jak wywoływanie metod klienta) za pomocą programu await . Następnie użyj co najmniej jednej z następujących metod:

  • Zawiń kod metody w blokach try-catch i zarejestruj obiekt wyjątku. Na potrzeby debugowania można wysłać wyjątek do klienta, ale ze względów bezpieczeństwa nie zaleca się wysyłania szczegółowych informacji do klientów w środowisku produkcyjnym.

  • Utwórz moduł potoków centrów, który obsługuje metodę OnIncomingError . W poniższym przykładzie przedstawiono moduł potoku, który rejestruje błędy, a następnie kod w Startup.cs, który wprowadza moduł do potoku centrów.

    public class ErrorHandlingPipelineModule : HubPipelineModule
    {
        protected override void OnIncomingError(ExceptionContext exceptionContext, IHubIncomingInvokerContext invokerContext)
        {
            Debug.WriteLine("=> Exception " + exceptionContext.Error.Message);
            if (exceptionContext.Error.InnerException != null)
            {
                Debug.WriteLine("=> Inner Exception " + exceptionContext.Error.InnerException.Message);
            }
            base.OnIncomingError(exceptionContext, invokerContext);
    
        }
    }
    
    public void Configuration(IAppBuilder app)
    {
        // Any connection or hub wire up and configuration should go here
        GlobalHost.HubPipeline.AddModule(new ErrorHandlingPipelineModule()); 
        app.MapSignalR();
    }
    
  • Użyj HubException klasy (wprowadzonej w sygnalizacji 2). Ten błąd może zostać zgłoszony z dowolnego wywołania piasty. HubErrorKonstruktor przyjmuje komunikat ciągu i obiekt do przechowywania dodatkowych danych o błędach. Sygnalizujący będzie autoserializować wyjątek i wyśle go do klienta, gdzie zostanie użyty do odrzucenia lub niepowodzenia wywołania metody centrum.

    Poniższy przykład kodu pokazuje, jak zgłosić HubException podczas wywołania centrum oraz jak obsłużyć wyjątek na klientach JavaScript i .NET.

    Kod serwera pokazujący klasę HubException

    public class MyHub : Hub
    {
        public async Task Send(string message)
        {
            if(message.Contains("<script>"))
            {
                throw new HubException("This message will flow to the client", new { user = Context.User.Identity.Name, message = message });
            }
    
            await Clients.All.send(message);
        }
    }
    

    Kod klienta JavaScript pokazujący odpowiedź na wyrzucanie HubException w centrum

    myHub.server.send("<script>")
                .fail(function (e) {
                    if (e.source === 'HubException') {
                        console.log(e.message + ' : ' + e.data.user);
                    }
                });
    

    Kod klienta platformy .NET pokazujący odpowiedź na wyrzucanie HubException w centrum

    try
    {
        await myHub.Invoke("Send", "<script>");
    }
    catch(HubException ex)
    {
        Console.WriteLine(ex.Message);
    }
    

Więcej informacji o modułach potoku centrów znajduje się w sekcji jak dostosować potok centrów w dalszej części tego tematu.

Jak włączyć śledzenie

Aby włączyć śledzenie po stronie serwera, Dodaj element System. Diagnostics do pliku Web.config, jak pokazano w tym przykładzie:

<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit https://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="SignalRSamples" connectionString="Data Source=(local);Initial Catalog=SignalRSamples;Integrated Security=SSPI;Asynchronous Processing=True;" />
    <add name="SignalRSamplesWithMARS" connectionString="Data Source=(local);Initial Catalog=SignalRSamples;Integrated Security=SSPI;Asynchronous Processing=True;MultipleActiveResultSets=true;" />
  </connectionStrings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
  </system.webServer>
  <system.diagnostics>
    <sources>
      <source name="SignalR.SqlMessageBus">
        <listeners>
          <add name="SignalR-Bus" />
        </listeners>
      </source>
     <source name="SignalR.ServiceBusMessageBus">
        <listeners>
            <add name="SignalR-Bus" />
        </listeners>
     </source>
     <source name="SignalR.ScaleoutMessageBus">
        <listeners>
            <add name="SignalR-Bus" />
        </listeners>
      </source>
      <source name="SignalR.Transports.WebSocketTransport">
        <listeners>
          <add name="SignalR-Transports" />
        </listeners>
      </source>
      <source name="SignalR.Transports.ServerSentEventsTransport">
          <listeners>
              <add name="SignalR-Transports" />
          </listeners>
      </source>
      <source name="SignalR.Transports.ForeverFrameTransport">
          <listeners>
              <add name="SignalR-Transports" />
          </listeners>
      </source>
      <source name="SignalR.Transports.LongPollingTransport">
        <listeners>
            <add name="SignalR-Transports" />
        </listeners>
      </source>
      <source name="SignalR.Transports.TransportHeartBeat">
        <listeners>
            <add name="SignalR-Transports" />
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="SignalRSwitch" value="Verbose" />
    </switches>
    <sharedListeners>
      <add name="SignalR-Transports" 
           type="System.Diagnostics.TextWriterTraceListener" 
           initializeData="transports.log.txt" />
        <add name="SignalR-Bus"
           type="System.Diagnostics.TextWriterTraceListener"
           initializeData="bus.log.txt" />
    </sharedListeners>
    <trace autoflush="true" />
  </system.diagnostics>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
</configuration>

Po uruchomieniu aplikacji w programie Visual Studio można wyświetlić dzienniki w oknie danych wyjściowych .

Jak wywoływać metody klienta i zarządzać grupami spoza klasy Hub

Aby wywołać metody klienta z innej klasy niż Klasa Hub, Pobierz odwołanie do obiektu kontekstu sygnalizującego dla centrum i użyj go do wywołania metod na kliencie lub zarządzania grupami.

Następująca Klasa Przykładowa StockTicker Pobiera obiekt kontekstu, zapisuje go w wystąpieniu klasy, zapisuje wystąpienie klasy w statycznej właściwości i używa kontekstu z wystąpienia klasy pojedynczej w celu wywołania updateStockPrice metody na klientach podłączonych do centrum o nazwie StockTickerHub .

// For the complete example, go to 
// http://www.asp.net/signalr/overview/getting-started/tutorial-server-broadcast-with-aspnet-signalr
// This sample only shows code related to getting and using the SignalR context.
public class StockTicker
{
    // Singleton instance
    private readonly static Lazy<StockTicker> _instance = new Lazy<StockTicker>(
        () => new StockTicker(GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>()));

    private IHubContext _context;

    private StockTicker(IHubContext context)
    {
        _context = context;
    }

    // This method is invoked by a Timer object.
    private void UpdateStockPrices(object state)
    {
        foreach (var stock in _stocks.Values)
        {
            if (TryUpdateStockPrice(stock))
            {
                _context.Clients.All.updateStockPrice(stock);
            }
        }
    }

Jeśli konieczne jest wielokrotne użycie kontekstu w obiekcie długim czasie, Pobierz odwołanie raz i Zapisz je, a nie ponownie za każdym razem. Uzyskanie kontekstu polega na tym, że sygnalizujący wyśle komunikaty do klientów w tej samej kolejności, w której metody centrum umożliwiają wywoływanie metody klienta. Aby zapoznać się z samouczkiem, który pokazuje, jak używać kontekstu sygnalizującego dla centrum, zobacz serwer Broadcast with ASP.NET signaler.

Wywoływanie metod klienta

Można określić, którzy klienci będą otrzymywać wywołania RPC, ale jest mniej opcji niż w przypadku wywołania z klasy centrum. Przyczyną jest to, że kontekst nie jest skojarzony z konkretnym wywołaniem z klienta, dlatego wszelkie metody wymagające znajomości bieżącego identyfikatora połączenia, takie jak Clients.Others , lub, Clients.Caller lub Clients.OthersInGroup , są niedostępne. Dostępne są następujące opcje:

  • Wszyscy połączeni klienci.

    context.Clients.All.addContosoChatMessageToPage(name, message);
    
  • Określony klient identyfikowany przez identyfikator połączenia.

    context.Clients.Client(connectionID).addContosoChatMessageToPage(name, message);
    
  • Wszyscy połączeni klienci z wyjątkiem określonych klientów identyfikowane przez identyfikator połączenia.

    context.Clients.AllExcept(connectionId1, connectionId2).addContosoChatMessageToPage(name, message);
    
  • Wszyscy połączeni klienci w określonej grupie.

    context.Clients.Group(groupName).addContosoChatMessageToPage(name, message);
    
  • Wszyscy połączeni klienci w określonej grupie z wyjątkiem określonych klientów identyfikowane przez identyfikator połączenia.

    Clients.Group(groupName, connectionId1, connectionId2).addContosoChatMessageToPage(name, message);
    

Jeśli wywołujesz klasę niebędącą centrami z metod w klasie centrów, możesz przekazać bieżący identyfikator połączenia i użyć go z Clients.Client , Clients.AllExcept , lub, Clients.Group Aby symulować Clients.Caller , Clients.Others lub Clients.OthersInGroup . W poniższym przykładzie MoveShapeHub Klasa przekazuje identyfikator połączenia do Broadcaster klasy, aby Broadcaster można było symulować klasę Clients.Others .

// For the complete example, see
// http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/tutorial-server-broadcast-with-signalr-20
// This sample only shows code that passes connection ID to the non-Hub class,
// in order to simulate Clients.Others.
public class MoveShapeHub : Hub
{
    // Code not shown puts a singleton instance of Broadcaster in this variable.
    private Broadcaster _broadcaster;

    public void UpdateModel(ShapeModel clientModel)
    {
        clientModel.LastUpdatedBy = Context.ConnectionId;
        // Update the shape model within our broadcaster
        _broadcaster.UpdateShape(clientModel);
    }
}

public class Broadcaster
{
    public Broadcaster()
    {
        _hubContext = GlobalHost.ConnectionManager.GetHubContext<MoveShapeHub>();
    }

    public void UpdateShape(ShapeModel clientModel)
    {
        _model = clientModel;
        _modelUpdated = true;
    }

    // Called by a Timer object.
    public void BroadcastShape(object state)
    {
        if (_modelUpdated)
        {
            _hubContext.Clients.AllExcept(_model.LastUpdatedBy).updateShape(_model);
            _modelUpdated = false;
        }
    }
}

Zarządzanie członkostwem w grupie

W przypadku zarządzania grupami te same opcje są takie same jak w klasie centrów.

  • Dodawanie klienta do grupy

    context.Groups.Add(connectionID, groupName);
    
  • Usuwanie klienta z grupy

    context.Groups.Remove(connectionID, groupName);
    

Jak dostosować potok centrów

Sygnalizujący umożliwia wprowadzanie własnego kodu do potoku centrum. W poniższym przykładzie przedstawiono niestandardowy moduł potoku, który rejestruje każde wywołanie metody przychodzącej odebrane od klienta i wywołania metody wychodzącej wywołanego na kliencie:

public class LoggingPipelineModule : HubPipelineModule 
{ 
    protected override bool OnBeforeIncoming(IHubIncomingInvokerContext context) 
    { 
        Debug.WriteLine("=> Invoking " + context.MethodDescriptor.Name + " on hub " + context.MethodDescriptor.Hub.Name); 
        return base.OnBeforeIncoming(context); 
    }   
    protected override bool OnBeforeOutgoing(IHubOutgoingInvokerContext context) 
    { 
        Debug.WriteLine("<= Invoking " + context.Invocation.Method + " on client hub " + context.Invocation.Hub); 
        return base.OnBeforeOutgoing(context); 
    } 
}

Następujący kod w pliku Startup.cs rejestruje moduł do uruchomienia w potoku centrum:

public void Configuration(IAppBuilder app) 
{ 
    GlobalHost.HubPipeline.AddModule(new LoggingPipelineModule()); 
    app.MapSignalR();
}

Istnieje wiele różnych metod, które można przesłonić. Aby uzyskać pełną listę, zobacz metody HubPipelineModule.