SignalR Self Host+MVC等多端消息推送服务(一)

yizhihongxing

“SignalR Self Host+MVC等多端消息推送服务(一)”是一篇介绍使用SignalR实现消息推送服务的教程。它包括了从安装SignalR到在MVC网站上实现消息推送的完整过程。

以下是该教程的详细攻略:

第一步:安装SignalR

在开始之前,我们应该下载并安装SignalR,可以通过NuGet包管理器来安装。使用以下命令来安装:

Install-Package Microsoft.AspNet.SignalR

第二步:创建SignalR Hub类

创建一个Hub类,用于将消息从服务器推送到客户端。可以为此使用Visual Studio的“添加新项”对话框,选择“SignalR Hub Class”模板。例如,如果我们要创建一个名为“ChatHub”的类,可以使用以下代码:

using Microsoft.AspNet.SignalR;
using System.Threading.Tasks;

namespace SignalRChat
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

在上面的代码中,我们创建了一个名为“SendMessage”的方法,该方法将消息发送到所有连接的客户端。我们还在方法的签名中使用了async和await关键字,以便异步发送广播。

需要注意的是,在SignalR中,方法名称用于标识客户端应调用的方法名称。在上面的代码中,我们使用了“ReceiveMessage”作为客户端应调用的方法名称。

第三步:配置SignalR

要配置SignalR,需要将其添加到Web应用程序的Startup.cs文件中。在ConfigureServices方法中添加以下代码:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddSignalR();
}

接下来,在Configure方法中,添加以下代码:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/chatHub");
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

在上面的代码中,我们首先使用app.UseRouting()将路由服务添加到管道中,然后使用app.UseEndpoints()将SignalR的终结点和MVC的默认控制器路由添加到管道中。

第四步:调用客户端方法

要从服务器端调用客户端方法,可以在Hub类中包含一个方法,该方法将指定的消息发送到 connected clients。例如,如果我们要使用JavaScript从客户端调用“ReceiveMessage”方法,可以执行以下操作:

var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

connection.on("ReceiveMessage", function (user, message) {
    console.log(user + " says " + message);
});

connection.start().then(function () {
    connection.invoke("SendMessage", "Alice", "Hello");
}).catch(function (err) {
    return console.error(err.toString());
});

在上面的代码中,我们首先使用signalR.HubConnectionBuilder()创建连接对象,然后在调用connection.on()方法时,将“ReceiveMessage”方法注册为客户端应接收的方法。最后,我们通过调用connection.invoke()方法来调用服务器上的“SendMessage”方法。在服务器上调用此方法后,客户端上注册的“ReceiveMessage”方法将被调用。

示例说明

示例1:群聊

下面是示例1的完整代码:

using Microsoft.AspNet.SignalR;
using System.Threading.Tasks;

namespace SignalRChat
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}
<!-- Views/Home/Index.cshtml -->
@{
    ViewData["Title"] = "Chat Room";
}
<h2>Chat Room</h2>
<input type="text" id="userInput" placeholder="user" />
<input type="text" id="messageInput" placeholder="message" />
<button id="sendButton">Send</button>
<div id="messages">
</div>
@section Scripts
{
    <script src="~/lib/signalr/dist/browser/signalr.js"></script>
    <script>
        var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

        connection.on("ReceiveMessage", function (user, message) {
            var encodedMsg = user + " says " + message;
            var li = document.createElement("li");
            li.textContent = encodedMsg;
            document.getElementById("messages").appendChild(li);
        });

        document.getElementById("sendButton").addEventListener("click", function (event) {
            var user = document.getElementById("userInput").value;
            var message = document.getElementById("messageInput").value;
            connection.invoke("SendMessage", user, message).catch(function (err) {
                return console.error(err.toString());
            });
            event.preventDefault();
        });

        connection.start().catch(function (err) {
            return console.error(err.toString());
        });
    </script>
}

在该示例中,我们实现一个简单的聊天室,允许用户输入其名称和消息,然后将消息广播到所有其他连接的客户端。用户在客户端输入名称和消息后,单击“发送”按钮。 将从客户端发送到服务器的消息称为“user”和“message”。 服务器会将此消息发送到所有连接的客户端,并更新消息列表。在客户端上,我们使用connection.invoke()方法调用服务器上的SendMessage方法,并使用on()方法订阅“ReceiveMessage”事件以接收广播消息。

示例2:实时显示股票价格

下面是示例2的完整代码:

using Microsoft.AspNet.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;

namespace SignalRStockTicker
{
    public class StockTicker
    {
        // Singleton instance
        private readonly static Lazy<StockTicker> _instance = new(() => new StockTicker(GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>().Clients));

        private readonly object _stockPricesLock = new();
        private readonly Random _updateOrNotRandom = new();
        private readonly Dictionary<string, Stock> _stocks = new();
        private readonly Timer _timer;
        private StockTicker(IHubConnectionContext<dynamic> clients)
        {
            Clients = clients;

            _stocks = GenerateStocks();

            _timer = new Timer
            {
                Interval = 2000
            };

            _timer.Elapsed += UpdateStockPrices;
        }

        private void UpdateStockPrices(object sender, ElapsedEventArgs e)
        {
            foreach (var stock in _stocks.Values)
            {
                if (_updateOrNotRandom.NextDouble() > 0.1)
                {
                    // In real life we'd query a database or other data source to get new stock prices.
                    // Here we'll just manipulate the existing data to make it look like a stock market.
                    var pos = _updateOrNotRandom.NextDouble() < 0.5 ? 1 : -1;
                    var change = _updateOrNotRandom.NextDouble() * 2.0;  //stock price between -2% and +2%
                    stock.Price += pos * change * stock.Price;
                    stock.Price = Math.Round(stock.Price, 2);

                    // This optional logic makes sure that the price change is no more than 10 percent.
                    var percentageChange = change * 100 / stock.Price;
                    if (Math.Abs(percentageChange) > 10)
                    {
                        stock.Price -= pos * change * stock.Price;
                        stock.Price = Math.Round(stock.Price, 2);
                    }

                    // Send the new stock price to all clients.
                    Clients.All.updateStockPrice(stock);
                }
            }
        }

        public static StockTicker Instance => _instance.Value;
        private IHubConnectionContext<dynamic> Clients { get; set; }

        public IEnumerable<Stock> GetAllStocks()
        {
            return _stocks.Values;
        }

        private Dictionary<string, Stock> GenerateStocks()
        {
            return new Dictionary<string, Stock>
            {
                { "MSFT", new Stock { Symbol = "MSFT", Price = 200.1m } },
                { "AAPL", new Stock { Symbol = "AAPL", Price = 400.2m } },
                { "GOOG", new Stock { Symbol = "GOOG", Price = 600.3m } },
                { "AMZN", new Stock { Symbol = "AMZN", Price = 800.4m } },
                { "FB", new Stock { Symbol = "FB", Price = 50.5m } }
            };
        }

        public void Start()
        {
            _timer.Start();
        }

        public void Stop()
        {
            _timer.Stop();
        }

        public Stock GetStock(string symbol)
        {
            var stock = new Stock { Symbol = "NOT FOUND", Price = 0m };

            if (_stocks.ContainsKey(symbol))
            {
                stock = _stocks[symbol];
            }

            return stock;
        }
    }

    public class Stock
    {
        public string Symbol { get; set; }
        public decimal Price { get; set; }
    }
}
using Microsoft.AspNet.SignalR;

namespace SignalRStockTicker
{
    public class StockTickerHub : Hub
    {
        private readonly StockTicker _stockTicker;

        public StockTickerHub() : this(StockTicker.Instance) { }

        public StockTickerHub(StockTicker stockTicker)
        {
            _stockTicker = stockTicker;
        }

        public void GetAllStocks()
        {
            var stocks = _stockTicker.GetAllStocks();
            Clients.Caller.updateAllStocks(stocks);
        }

        public void GetStock(string symbol)
        {
            var stock = _stockTicker.GetStock(symbol);
            Clients.Caller.updateStockPrice(stock);
        }
    }
}
<!-- Views/Home/Index.cshtml -->
@{
    ViewData["Title"] = "Stock Ticker";
}
<h2>Stock Ticker</h2>
<div id="stocks-list">
</div>
<div id="stock-price">
</div>
@section Scripts
{
    <script src="~/lib/signalr/dist/browser/signalr.js"></script>
    <script>
        var connection = new signalR.HubConnectionBuilder().withUrl("/stockTickerHub").build();

        connection.on("updateAllStocks", function (stocks) {
            var table = document.createElement("table");
            for (stock of stocks) {
                var row = document.createElement("tr");
                var symbolCell = document.createElement("td");
                var priceCell = document.createElement("td");
                symbolCell.textContent = stock.symbol;
                priceCell.textContent = stock.price;
                row.appendChild(symbolCell);
                row.appendChild(priceCell);
                table.appendChild(row);
            }
            document.getElementById("stocks-list").appendChild(table);
        });

        connection.on("updateStockPrice", function (stock) {
            // Update the stock price.
            document.getElementById("stock-price").textContent =
                stock.symbol + ": " + stock.price;
        });

        connection.start().then(function () {
            connection.invoke("GetAllStocks").catch(function (err) {
                return console.error(err.toString());
            });
        });

        setInterval(function () {
            var symbols = ['MSFT', 'AAPL', 'GOOG', 'AMZN', 'FB'];
            var symbol = symbols[Math.floor(Math.random() * symbols.length)];
            connection.invoke("GetStock", symbol).catch(function (err) {
                return console.error(err.toString());
            });
        }, 1000);
    </script>
}

在此示例中,我们使用StockTicker类和StockTickerHub类创建了一个简单的股票行情跟踪器。其中StockTicker是一个单例,用于在一定时间间隔内更新所有股票价格的模拟数据,并将更新后的股票价格发送给所有连接的客户端。StockTickerHub则包含两个方法,分别用于获取所有股票价格和特定股票的价格,并使用Clients对象将数据发送到客户端。

在客户端上,我们使用connection.on()方法订阅“updateAllStocks”和“updateStockPrice”事件。当连接成功时,我们通过connection.invoke()方法调用服务器上的GetAllStocks方法,以获取所有股票价格。我们还使用javascript中的setInterval()函数,每秒调用服务器上的GetStock方法,随机地请求一个股票的价格,并实时更新股票价格。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SignalR Self Host+MVC等多端消息推送服务(一) - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Windows Phone 8.1完结:正式停止接收应用更新

    Windows Phone 8.1停止接收应用更新攻略 微软在2017年7月11日正式停止了Windows Phone 8.1的支持,包括停止对该系统的安全更新、修复漏洞等的更新,也包括停止接收应用程序的更新。 为什么要停止接收应用更新? Windows Phone 8.1是微软的旧操作系统,其用户量已经大幅下降,并且这个系统已经过时且不再受支持。大部分开发…

    other 2023年6月25日
    00
  • mstp配置实例

    以下是关于“MSTP配置实例”的完整攻略,包含两个示例说明。 MSTP配置实例 MSTP(Multiple Spanning Tree Protocol)是一种用于在网络中防止环的协议。在本攻略中,我们将介绍如何配置MSTP以及如何在网络中使用MSTP。 1. 配置MSTP 在配置MSTP之前,我们需要确保网络中的所有设备都支持MSTP。以下是一个示例: i…

    other 2023年5月9日
    00
  • 操作系统的功能

    操作系统是一种管理计算机硬件与软件资源的系统软件。它可以协调不同的应用程序、管理系统资源,以及处理计算机的输入与输出等操作,使得计算机可以更加高效、稳定地运行。 操作系统的主要功能如下: 进程管理 操作系统负责分配和管理计算机系统的进程,确保它们在不同的阶段下拥有足够的资源和优先级。例如,在一个多任务系统中,操作系统可以保证计算机的 CPU 时间被正确地分配…

    其他 2023年4月16日
    00
  • 【自制插件】mmd4maya

    【自制插件】mmd4maya的完整攻略 mmd4maya是一款用于在Maya中导入和编辑MikuMikuDance(MMD)模型和动画的插件。本文将介绍如何安装和使用mmd4maya,并提供两个示例说明。 步骤1:安装mmd4maya 要安装mmd4maya,可以按照以下步骤操作: 下载mmd4maya插件文件。 将插件文件解压缩到Maya的插件目录中。在W…

    other 2023年5月6日
    00
  • vue接口日常学习

    Vue接口日常学习攻略 Vue是一款流行的JavaScript框架,可以帮助开发者快速构建交互式的Web应用程序。在Vue应用程序中,接口是非常重要的一部,它可以帮应用程序与后端服务器进行通信。本攻略将详细讲解如何学习Vue接口日常开发。 步骤 以下是习Vue接口日常开发的步骤: 学习基本的HTTP协议:在学习Vue接口日常开发之前,需要了解HTTP协议的基…

    other 2023年5月9日
    00
  • mysql 中如何取得汉字字段的各汉字首字母

    在 MySQL 中,可以使用 SUBSTRING() 函数、ASCII() 函数和REPLACE()函数来实现取得汉字字段的各汉字首字母。以下是具体的步骤: 步骤1:使用 SELECT 语句选择要获取首字母的汉字字段,例如表名为 table1,汉字字段名为 name,可以执行如下语句: SELECT name FROM table1; 步骤2:将汉字字段转换…

    other 2023年6月25日
    00
  • 黑客七大惯用攻击策略(攻击与防范)

    1. 概述 黑客的攻击手段层出不穷,但是它们通常沿用着某些基本的攻击策略,并将其不断细化、扩展,进而形成复杂多变的攻击手段。为此,我们需要了解黑客的攻击手段,掌握相应的防范措施,以在安全威胁面前保护好我们的网络安全。 在黑客攻击中,有七种惯用攻击策略,分别是枚举、弱点扫描、漏洞利用、密码攻击、社会工程学、拒绝服务攻击和木马攻击。下面将详细介绍黑客攻击的七种惯…

    other 2023年6月26日
    00
  • 企业信息防泄漏产品、如何加强网络信息安全、网络信息安全解决方案

    企业信息防泄漏产品攻略 企业信息防泄漏产品可以帮助企业有效地保护企业内部的信息安全,避免敏感信息被泄露的风险,因此在企业中使用这些产品具有非常重要的意义。 选择合适的防泄漏产品 在选择企业信息防泄漏产品时,需要考虑以下几个方面: 功能:产品要能够满足企业的需求,例如可以监测、阻止既定规则外的信息传输,对设备进行远程管理等。 支持的操作系统:产品要支持企业所有…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部