【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 = 10;
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

转载于:https://www.cnblogs.com/Soulless/p/7241125.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 ASP.NET MVC 中使用 SignalR 实现推送功能需要以下步骤: 1. 在 Visual Studio 中创建一个 ASP.NET MVC 项目。 2. 通过 NuGet 安装 SignalR 库。 3. 创建一个 SignalR Hub 类。Hub 类是用来处理客户端和服务器之间的连接和消息传递的核心组件。 4. 在 Startup.cs 中配置 SignalR 中间件。 5. 在客户端 JavaScript 中引用 SignalR 库,并连接到 SignalR Hub。 6. 在 SignalR Hub 中定义需要推送的消息方法,然后在服务器端调用该方法以向客户端发送消息。 下面是一个简单的示例: 1. 创建一个名为 ChatHubSignalR Hub 类: ```csharp using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace MvcSignalR.Hubs { public class ChatHub : Hub { public async Task SendMessage(string user, string message) { await Clients.All.SendAsync("ReceiveMessage", user, message); } } } ``` 2. 在 Startup.cs 中配置 SignalR 中间件: ```csharp using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using MvcSignalR.Hubs; namespace MvcSignalR { public class Startup { public IConfiguration Configuration { get; } public Startup(IConfiguration configuration) { Configuration = configuration; } public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddSignalR(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseStaticFiles(); app.UseSignalR(routes => { routes.MapHub<ChatHub>("/chathub"); }); app.UseMvcWithDefaultRoute(); } } } ``` 3. 在客户端 JavaScript 中引用 SignalR 库,并连接到 SignalR Hub: ```javascript <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script src="/lib/signalr/dist/browser/signalr.js"></script> <script> var connection = new signalR.HubConnectionBuilder().withUrl("/chathub").build(); connection.start().then(function () { console.log("connected"); }).catch(function (err) { return console.error(err.toString()); }); connection.on("ReceiveMessage", function (user, message) { console.log(user + " says " + message); }); $("#sendButton").click(function () { var user = $("#userInput").val(); var message = $("#messageInput").val(); connection.invoke("SendMessage", user, message).catch(function (err) { return console.error(err.toString()); }); }); </script> ``` 4. 在 SignalR Hub 中定义需要推送的消息方法,然后在服务器端调用该方法以向客户端发送消息。 在这个示例中,当客户端调用 SendMessage 方法时,服务器将向所有连接的客户端发送 ReceiveMessage 消息。 以上就是在 ASP.NET MVC 中使用 SignalR 实现推送功能的基本步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值