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 :
- gustavo-armenta / SignalR-Samples sur GitHub.com (WinRT, Silverlight, exemples d’applications console).
- DamianEdwards / SignalR-MoveShapeDemo / MoveShape.Desktop sur GitHub.com (exemple WPF).
- SignalR / Microsoft.AspNet.SignalR.Client.Samples sur GitHub.com (exemple d’application console).
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
, updatestockprice
ou 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));