【SignalR学习系列】8. SignalR Hubs Api 详解(.Net C# 客户端)
建立一个 SignalR 连接
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();
配置 SignalR 连接
在 WPF 客户端里设置连接的最大值
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 = ;
await hubConnection.Start();
设置 Query String 参数
var querystringData = new Dictionary<string, string>();
querystringData.Add("contosochatversion", "1.0");
var connection = new HubConnection("http://contoso.com/", querystringData);
读取 query string
public class StockTickerHub : Hub
{
public override Task OnConnected()
{
var version = Context.QueryString["contosochatversion"];
if (version != "1.0")
{
Clients.Caller.notifyWrongVersion();
}
return base.OnConnected();
}
}
指定传输协议
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());
可以指定以下四种方式
- LongPollingTransport
- ServerSentEventsTransport
- WebSocketTransport (只有在 server and client 都使用 .NET 4.5的情况下才能使用)
- AutoTransport(自动选择)
指定 Http Header
hubConnection = new hubConnection("http://www.contoso.com/");
connection.Headers.Add("headername", "headervalue");
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await connection.Start();
指定 Client 证书
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();
创建 Hub proxy
服务端
public class StockTickerHub : 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();
如果你的 Hub 类使用了 HubName 特性,那么就需要使用 HubName 的值来调用。
服务端
[HubName("stockTicker")]
public class StockTickerHub : 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();
如果使用 HubName 多次调用 HubConnection.CreateHubProxy,那么会得到缓存的相同的 IHubProxy 对象。
如何定义在 Server 端调用的 Client 方法
无参方法
Server 端
public class StockTickerHub : Hub
{
public void NotifyAllClients()
{
Clients.All.Notify();
}
}
客户端
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();
有参指定参数类型
Sever 端
public void BroadcastStockPrice(Stock stock)
{
context.Clients.Others.UpdateStockPrice(stock);
}
用作参数的 Stock 类
public class Stock
{
public string Symbol { get; set; }
public decimal Price { get; set; }
}
客户端代码
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)
);
有参,指定动态类型
server 端
public void BroadcastStockPrice(Stock stock)
{
context.Clients.Others.UpdateStockPrice(stock);
}
用作参数的 Stock 类
public class Stock
{
public string Symbol { get; set; }
public decimal Price { get; set; }
}
客户端代码
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)
);
移除Handler
var updateStockPriceHandler = stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock =>
Context.Post(delegate
{
textBox.Text += string.Format("Stock update for {0} new price {1}\n", stock.Symbol, stock.Price);
}, null)
);
updateStockPriceHandler.Dispose();
从客户端调用服务端方法
使用 HubProxy 的 Invoke 方法来调用服务端的方法。
服务端方法没有返回值
public class StockTickerHub : Hub
{
public void JoinGroup(string groupName)
{
Groups.Add(Context.ConnectionId, groupName);
}
}
客户端调用服务器没有返回值的方法
stockTickerHubProxy.Invoke("JoinGroup", "SignalRChatRoom");
服务端方法有返回值,并且有一个复杂类型的参数
public IEnumerable<Stock> AddStock(Stock stock)
{
_stockTicker.AddStock(stock);
return _stockTicker.GetAllStocks();
}
Stock 类
public class Stock
{
public string Symbol { get; set; }
public decimal Price { get; set; }
}
客户端调用有返回值和复杂类型参数的方法,.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);
}
如何处理连接的生命周期事件
SignalR 提供了下述你可以捕获的生命周期事件。
- received: 当任何数据通过连接获取到的时候执行。可以得到数据。
- connectionSlow: 当客户端检测到缓慢或者不流畅的连接的时候执行。
- reconnecting: 当潜在的协议重新开始连接的时候执行。
- reconnected: 当潜在的协议以及重新建立连接的时候执行。
- stateChanged: 当连接的状态发生改变的时候执行。可以提供一个旧的和新的状态(Connecting, Connected, Reconnecting, 或者 Disconnected)。
- Closed: 当连接中断以后执行。
hubConnection.ConnectionSlow += () => Console.WriteLine("Connection problems.");
捕获异常
如果你不在服务端明确地打开详细错误信息,那么SignalR只会列出一些简单的错误信息,你可以通过下面的代码开启详细错误信息记录。
var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableDetailedErrors = true;
App.MapSignalR(hubConfiguration);
给 connection 对象添加一个 error 处理事件。
hubConnection.Error += ex => Console.WriteLine("SignalR error: {0}", ex.Message);
用 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);
}
开启客户端日志
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();
参考链接:
https://docs.microsoft.com/zh-cn/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-net-client
【SignalR学习系列】8. SignalR Hubs Api 详解(.Net C# 客户端)的更多相关文章
- 【SignalR学习系列】7. SignalR Hubs Api 详解(JavaScript 客户端)
SignalR 的 generated proxy 服务端 public class ContosoChatHub : Hub { public void NewContosoChatMessage( ...
- prometheus学习系列十一: Prometheus exporter详解
exporter详解 前面的系列中,我们在主机上面安装了node_exporter程序,该程序对外暴露一个用于获取当前监控样本数据的http的访问地址, 这个的一个程序成为exporter,Expor ...
- 【SignalR学习系列】6. SignalR Hubs Api 详解(C# Server 端)
如何注册 SignalR 中间件 为了让客户端能够连接到 Hub ,当程序启动的时候你需要调用 MapSignalR 方法. 下面代码显示了如何在 OWIN startup 类里面定义 SignalR ...
- 【HANA系列】SAP HANA XS的JavaScript API详解
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA XS的Java ...
- 【HANA系列】【第五篇】SAP HANA XS的JavaScript API详解
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列][第五篇]SAP HANA XS ...
- hibernate学习(2)——api详解对象
1 Configuration 配置对象 /详解Configuration对象 public class Configuration_test { @Test //Configuration 用户 ...
- Java8学习笔记(五)--Stream API详解[转]
为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 ...
- Lucene系列六:Lucene搜索详解(Lucene搜索流程详解、搜索核心API详解、基本查询详解、QueryParser详解)
一.搜索流程详解 1. 先看一下Lucene的架构图 由图可知搜索的过程如下: 用户输入搜索的关键字.对关键字进行分词.根据分词结果去索引库里面找到对应的文章id.根据文章id找到对应的文章 2. L ...
- 大数据学习笔记——Spark工作机制以及API详解
Spark工作机制以及API详解 本篇文章将会承接上篇关于如何部署Spark分布式集群的博客,会先对RDD编程中常见的API进行一个整理,接着再结合源代码以及注释详细地解读spark的作业提交流程,调 ...
随机推荐
- 深入浅出 spring-data-elasticsearch - 基本案例详解(三
『 风云说:能分享自己职位的知识的领导是个好领导. 』运行环境:JDK 7 或 8,Maven 3.0+技术栈:SpringBoot 1.5+, Spring Data Elasticsearch ...
- phpcms v9 调用自定义字段多图片的第一张或第N张图为缩略图
1.打开相应要使用组图的模型的组图字段,添加组图 字段提示为 <div class="content_attr"> <label><input typ ...
- RabbitMQ安装与初始配置
[TOC] 本文只讨论linux下的Rabbitmq安装. Erlang安装 rabbitmq依赖于Erlang,需先安装,推荐安装rabbitmq/erlang-rpm: #clone源码 git ...
- Visual Studio 2017 for Mac 体验之Android.Form
微软官方说明: Visual Studio 2017 for Mac Last Update: 2017/6/16 我们非常荣幸地宣布 Visual Studio 2017 for Mac 现已推出. ...
- ASP.NET Core 源码学习之 Options[4]:IOptionsMonitor
前面我们讲到 IOptions 和 IOptionsSnapshot,他们两个最大的区别便是前者注册的是单例模式,后者注册的是 Scope 模式.而 IOptionsMonitor 则要求配置源必须是 ...
- Latex加速: TexStudio的安装和使用
TexStudio可以加速Latex的编辑和写作,这里简单介绍一下TexStudio的安装,配置和使用.但是有一个重要的前提,TexStudio会使Latex源代码和pdf文件并排显示,比较占用桌面的 ...
- 关于CSS3中transform变换的小坑
2017年6月30日15:05:46 今天在写一个demo的时候,发现CSS3中transform变换的一个特性. 首先,我先描述一下我发现的情况(问题再现): <div class=" ...
- Dagger2在Android开发中的应用
世界是普遍联系的,任何事物和个体都直接或间接相互依赖,在时空长河中共同发展.在面向对象的世界中,更是如此,类与类之间的依赖,关联关系,模块(亦或是分层架构中的层)之间的耦合关系,都是我们在软件开发实践 ...
- Python3 从入门到出门
引:此文是自己学习python过程中的笔记和总结,适合有语言基础的人快速了解python3和没基础的作为学习的大纲,了解学习的方向:笔记是从多本书和视频上学习后的整合版. (一)初识python 1. ...
- Tomcat集群搭建
关于如何搭建Tomcat集群网上还是能搜到很多相关的教程,这里结合我自己在实际应用中的操作做下备忘. 案例说明: 这里以在本机部署的2个tomcat来做集群.当然,tomcat集群可以是分布式的,而差 ...