Partager via


ASP.NET Guide de l’API SignalR Hubs - Client .NET (SignalR 1.x)

par Patrick Fletcher, Tom Dykstra

Avertissement

Cette documentation ne concerne pas la dernière version de SignalR. Consultez ASP.NET Core SignalR.

Ce document fournit une introduction à l’utilisation de l’API Hubs pour SignalR version 2 dans les clients .NET, tels que les applications Windows Store (WinRT), WPF, Silverlight et console.

L’API SignalR Hubs vous permet d’effectuer des appels de procédure à distance (RPC) à partir d’un serveur vers des clients connectés et de clients vers le serveur. Dans le code du serveur, vous définissez des méthodes qui peuvent être appelées par les clients et vous appelez des méthodes qui s’exécutent sur le client. Dans le code client, vous définissez des méthodes qui peuvent être appelées à partir du serveur et vous appelez des méthodes qui s’exécutent sur le serveur. SignalR prend en charge toute la plomberie client à serveur pour vous.

SignalR propose également une API de niveau inférieur appelée Connexions persistantes. Pour une présentation de SignalR, hubs et connexions persistantes, ou pour un tutoriel qui montre comment créer une application SignalR complète, consultez SignalR - Prise en main.

Vue d’ensemble

Ce document contient les sections suivantes :

Pour obtenir un exemple de projet client .NET, consultez les ressources suivantes :

Pour obtenir de la documentation sur la programmation du serveur ou des clients JavaScript, consultez les ressources suivantes :

Les liens vers les rubriques de référence de l’API sont vers la version .NET 4.5 de l’API. Si vous utilisez .NET 4, consultez la version .NET 4 des rubriques de l’API.

Configuration cliente

Installez le package NuGet Microsoft.AspNet.SignalR.Client (et non le package Microsoft.AspNet.SignalR ). Ce package prend en charge les clients WinRT, Silverlight, WPF, application console et Windows Phone, pour .NET 4 et .NET 4.5.

Si la version de SignalR que vous avez sur le client est différente de celle que vous avez sur le serveur, SignalR est souvent en mesure de s’adapter à la différence. Par exemple, lorsque SignalR version 2.0 est publiée et que vous l’installez sur le serveur, le serveur prend en charge les clients sur lesquels 1.1.x est installé, ainsi que les clients sur lesquels la version 2.0 est installée. Si la différence entre la version sur le serveur et la version sur le client est trop grande, SignalR lève une InvalidOperationException exception lorsque le client tente d’établir une connexion. Le message d’erreur est «You are using a version of the client that isn't compatible with the server. Client version X.X, server version X.X ».

Comment établir une connexion

Avant d’établir une connexion, vous devez créer un HubConnection objet et créer un proxy. Pour établir la connexion, appelez la Start méthode sur l’objet HubConnection .

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

Notes

Pour les clients JavaScript, vous devez inscrire au moins un gestionnaire d’événements avant d’appeler la Start méthode pour établir la connexion. Cela n’est pas nécessaire pour les clients .NET. Pour les clients JavaScript, le code proxy généré crée automatiquement des proxys pour tous les hubs qui existent sur le serveur, et l’inscription d’un gestionnaire est la façon dont vous indiquez les Hubs que votre client envisage d’utiliser. Toutefois, pour un client .NET, vous créez manuellement des proxys Hub. SignalR suppose donc que vous allez utiliser n’importe quel hub pour lequel vous créez un proxy.

L’exemple de code utilise l’URL « /signaleur » par défaut pour se connecter à votre service SignalR. Pour plus d’informations sur la façon de spécifier une autre URL de base, consultez ASP.NET Guide de l’API SignalR Hubs - Serveur - URL /signalr.

La Start méthode s’exécute de manière asynchrone. Pour vous assurer que les lignes de code suivantes ne s’exécutent qu’après l’établissement de la connexion, utilisez await dans une méthode asynchrone ASP.NET 4.5 ou .Wait() dans une méthode synchrone. N’utilisez .Wait() pas dans un client WinRT.

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

La classe HubConnection est thread-safe.

Connexions inter-domaines à partir de clients Silverlight

Pour plus d’informations sur l’activation des connexions inter-domaines à partir de clients Silverlight, consultez Mise à disposition d’un service au-delà des limites de domaine.

Comment configurer la connexion

Avant d’établir une connexion, vous pouvez spécifier l’une des options suivantes :

  • Limite des connexions simultanées.
  • Paramètres de chaîne de requête.
  • Méthode de transport.
  • En-têtes HTTP.
  • Certificats clients.

Comment définir le nombre maximal de connexions simultanées dans les clients WPF

Dans les clients WPF, vous devrez peut-être augmenter le nombre maximal de connexions simultanées à partir de sa valeur par défaut de 2. La valeur recommandée est 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();

Pour plus d’informations, consultez ServicePointManager.DefaultConnectionLimit.

Comment spécifier des paramètres de chaîne de requête

Si vous souhaitez envoyer des données au serveur lorsque le client se connecte, vous pouvez ajouter des paramètres de chaîne de requête à l’objet de connexion. L’exemple suivant montre comment définir un paramètre de chaîne de requête dans le code client.

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

L’exemple suivant montre comment lire un paramètre de chaîne de requête dans le code du serveur.

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

Comment spécifier la méthode de transport

Dans le cadre du processus de connexion, un client SignalR négocie normalement avec le serveur pour déterminer le meilleur transport pris en charge par le serveur et le client. Si vous savez déjà quel transport vous souhaitez utiliser, vous pouvez contourner ce processus de négociation. Pour spécifier la méthode de transport, transmettez un objet de transport à la méthode Start. L’exemple suivant montre comment spécifier la méthode de transport dans le code 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(new LongPollingTransport());

L’espace de noms Microsoft.AspNet.SignalR.Client.Transports comprend les classes suivantes que vous pouvez utiliser pour spécifier le transport.

  • LongPollingTransport
  • ServerSentEventsTransport
  • WebSocketTransport (Disponible uniquement lorsque le serveur et le client utilisent .NET 4.5.)
  • AutoTransport (choisit automatiquement le meilleur transport pris en charge à la fois par le client et le serveur. Il s’agit du transport par défaut. La transmission de cette valeur à la Start méthode a le même effet que de ne rien transmettre.)

Le transport ForeverFrame n’est pas inclus dans cette liste, car il est utilisé uniquement par les navigateurs.

Pour plus d’informations sur la façon de case activée la méthode de transport dans le code du serveur, consultez ASP.NET Guide de l’API SignalR Hubs - Serveur - Comment obtenir des informations sur le client à partir de la propriété Context. Pour plus d’informations sur les transports et les secours, consultez Présentation de SignalR - Transports et secours.

Comment spécifier des en-têtes HTTP

Pour définir des en-têtes HTTP, utilisez la Headers propriété sur l’objet de connexion. L’exemple suivant montre comment ajouter un en-tête 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();

Comment spécifier des certificats clients

Pour ajouter des certificats clients, utilisez la AddClientCertificate méthode sur l’objet de connexion.

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

Comment créer le proxy Hub

Pour définir des méthodes sur le client qu’un hub peut appeler à partir du serveur, et pour appeler des méthodes sur un hub sur le serveur, créez un proxy pour le hub en appelant CreateHubProxy sur l’objet de connexion. La chaîne à CreateHubProxy laquelle vous passez est le nom de votre classe Hub ou le nom spécifié par l’attribut HubName s’il a été utilisé sur le serveur. La correspondance de noms ne respecte pas la casse.

Classe Hub sur le serveur

public class StockTickerHub : Hub

Créer un proxy client pour la classe 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();

Si vous décorez votre classe Hub avec un HubName attribut, utilisez ce nom.

Classe Hub sur le serveur

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

Créer un proxy client pour la classe 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();

L’objet proxy est thread-safe. En fait, si vous appelez HubConnection.CreateHubProxy plusieurs fois avec le même hubName, vous obtenez le même objet mis en IHubProxy cache.

Comment définir des méthodes sur le client que le serveur peut appeler

Pour définir une méthode que le serveur peut appeler, utilisez la méthode du On proxy pour inscrire un gestionnaire d’événements.

La correspondance de nom de méthode ne respecte pas la casse. Par exemple, Clients.All.UpdateStockPrice sur le serveur exécute updateStockPrice, updatestockpriceou UpdateStockPrice sur le client.

Les différentes plateformes clientes ont des exigences différentes pour la façon dont vous écrivez le code de méthode pour mettre à jour l’interface utilisateur. Les exemples présentés concernent les clients WinRT (Windows Store .NET). Les exemples d’applications WPF, Silverlight et console sont fournis dans une section distincte plus loin dans cette rubrique.

Méthodes sans paramètres

Si la méthode que vous gérez n’a pas de paramètres, utilisez la surcharge non générique de la On méthode :

Méthode cliente d’appel de code de serveur sans paramètres

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

Code client WinRT pour la méthode appelée à partir d’un serveur sans paramètres (voir exemples WPF et Silverlight plus loin dans cette rubrique)

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

Méthodes avec des paramètres, spécifiant les types de paramètres

Si la méthode que vous gérez a des paramètres, spécifiez les types des paramètres comme types génériques de la On méthode. Il existe des surcharges génériques de la On méthode pour vous permettre de spécifier jusqu’à 8 paramètres (4 sur Windows Phone 7). Dans l’exemple suivant, un paramètre est envoyé à la UpdateStockPrice méthode .

Méthode cliente appelant le code serveur avec un paramètre

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

Classe Stock utilisée pour le paramètre

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

Code client WinRT pour une méthode appelée à partir du serveur avec un paramètre (voir exemples WPF et Silverlight plus loin dans cette rubrique)

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

Méthodes avec des paramètres, spécifiant des objets dynamiques pour les paramètres

Au lieu de spécifier des paramètres en tant que types génériques de la On méthode, vous pouvez spécifier des paramètres en tant qu’objets dynamiques :

Méthode cliente appelant le code serveur avec un paramètre

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

Classe Stock utilisée pour le paramètre

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

Code client WinRT pour une méthode appelée à partir du serveur avec un paramètre, à l’aide d’un objet dynamique pour le paramètre (voir exemples WPF et Silverlight plus loin dans cette rubrique)

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

Comment supprimer un gestionnaire

Pour supprimer un gestionnaire, appelez sa Dispose méthode.

Code client pour une méthode appelée à partir du serveur

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

Code client pour supprimer le gestionnaire

updateStockPriceHandler.Dispose();

Comment appeler des méthodes serveur à partir du client

Pour appeler une méthode sur le serveur, utilisez la Invoke méthode sur le proxy Hub.

Si la méthode serveur n’a aucune valeur de retour, utilisez la surcharge non générique de la Invoke méthode.

Code serveur pour une méthode qui n’a aucune valeur de retour

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

Code client appelant une méthode qui n’a aucune valeur de retour

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

Si la méthode serveur a une valeur de retour, spécifiez le type de retour comme type générique de la Invoke méthode.

Code serveur pour une méthode qui a une valeur de retour et prend un paramètre de type complexe

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

Classe Stock utilisée pour le paramètre et la valeur de retour

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

Code client appelant une méthode qui a une valeur de retour et prend un paramètre de type complexe, dans une méthode asynchrone 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);
}

Code client appelant une méthode qui a une valeur de retour et prend un paramètre de type complexe, dans une méthode synchrone

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

La Invoke méthode s’exécute de manière asynchrone et retourne un Task objet. Si vous ne spécifiez await pas ou .Wait(), la ligne de code suivante s’exécutera avant la fin de l’exécution de la méthode que vous appelez.

Comment gérer les événements de durée de vie de connexion

SignalR fournit les événements de durée de vie de connexion suivants que vous pouvez gérer :

  • Received: déclenché lorsque des données sont reçues sur la connexion. Fournit les données reçues.
  • ConnectionSlow: déclenché lorsque le client détecte une connexion lente ou fréquente.
  • Reconnecting: déclenché lorsque le transport sous-jacent commence à se reconnecter.
  • Reconnected: déclenché lorsque le transport sous-jacent s’est reconnecté.
  • StateChanged: déclenché lorsque l’état de la connexion change. Fournit l’ancien état et le nouvel état. Pour plus d’informations sur les valeurs d’état de connexion, consultez Énumération ConnectionState.
  • Closed: déclenché lorsque la connexion est déconnectée.

Par exemple, si vous souhaitez afficher des messages d’avertissement pour les erreurs qui ne sont pas irrécupérables, mais qui provoquent des problèmes de connexion intermittents, tels que la lenteur ou l’abandon fréquent de la connexion, gérez l’événement ConnectionSlow .

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

Pour plus d’informations, consultez Compréhension et gestion des événements de durée de vie de connexion dans SignalR.

Comment gérer les erreurs

Si vous n’activez pas explicitement les messages d’erreur détaillés sur le serveur, l’objet d’exception retourné par SignalR après une erreur contient un minimum d’informations sur l’erreur. Par exemple, si un appel à newContosoChatMessage échoue, le message d’erreur dans l’objet d’erreur contient «There was an error invoking Hub method 'contosoChatHub.newContosoChatMessage'. » L’envoi de messages d’erreur détaillés aux clients en production n’est pas recommandé pour des raisons de sécurité, mais si vous souhaitez activer les messages d’erreur détaillés à des fins de résolution des problèmes, utilisez le code suivant sur le serveur.

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

Pour gérer les erreurs que SignalR génère, vous pouvez ajouter un gestionnaire pour l’événement Error sur l’objet de connexion.

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

Pour gérer les erreurs des appels de méthode, encapsulez le code dans un bloc 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);
}

Comment activer la journalisation côté client

Pour activer la journalisation côté client, définissez les TraceLevel propriétés et TraceWriter sur l’objet de connexion.

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

Exemples de code d’application WPF, Silverlight et console pour les méthodes clientes que le serveur peut appeler

Les exemples de code présentés précédemment pour définir les méthodes clientes que le serveur peut appeler s’appliquent aux clients WinRT. Les exemples suivants montrent le code équivalent pour les clients d’application wpF, Silverlight et console.

Méthodes sans paramètres

Code client WPF pour la méthode appelée à partir du serveur sans paramètres

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

Code client Silverlight pour la méthode appelée à partir du serveur sans paramètres

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

Code client de l’application console pour la méthode appelée à partir du serveur sans paramètres

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

Méthodes avec des paramètres, spécifiant les types de paramètres

Code client WPF pour une méthode appelée à partir du serveur avec un paramètre

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

Code client Silverlight pour une méthode appelée à partir du serveur avec un paramètre

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

Code client d’application console pour une méthode appelée à partir du serveur avec un paramètre

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

Méthodes avec des paramètres, spécifiant des objets dynamiques pour les paramètres

Code client WPF pour une méthode appelée à partir du serveur avec un paramètre, à l’aide d’un objet dynamique pour le paramètre

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

Code client Silverlight pour une méthode appelée à partir du serveur avec un paramètre, à l’aide d’un objet dynamique pour le paramètre

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

Code client d’application console pour une méthode appelée à partir du serveur avec un paramètre, à l’aide d’un objet dynamique pour le paramètre

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