zoukankan      html  css  js  c++  java
  • 【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!
    ";
        }, 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}
    ", 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}
    ", 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}
    ", 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}
    ", 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
  • 相关阅读:
    nohup npm start &启动之后关闭终端程序没有后台运行
    C++标准库之string返回值研究
    Apache Thrift的C++多线程编程定式
    实战C++对象模型之成员函数调用
    std::string的拷贝赋值研究
    REdis AOF文件结构分析
    使用Linux自带日志滚动工具logrotate滚动redis日志示例
    源码分析MySQL mysql_real_query函数
    源码解读Linux的limits.conf文件
    C++中的return和exit区别
  • 原文地址:https://www.cnblogs.com/webenh/p/9560492.html
Copyright © 2011-2022 走看看