Asp.net core 使用SignalR推送消息过程详解

Asp.net core 使用SignalR推送消息过程详解

SignalR是一个基于ASP.NET Core的实时通讯框架,允许服务器端代码通过WebSockets、Server-Sent Events (SSE)、Long Polling或Forever Frame等协议向客户端推送消息,同时也支持客户端向服务器端发送消息。

SignalR的核心组件是Hub,它支持在客户端与服务端之间进行双向通信,收到服务端的推送消息后,客户端可以实时更新UI界面。

下面就来详细讲解如何在Asp.net core中使用SignalR推送消息。

步骤一: 创建Asp.net core web应用程序,并添加SignalR支持

打开Visual Studio然后新建一个Asp.net core web应用程序。

然后在Startup.cs中添加SignalR支持,我们需要在ConfigureServices方法中添加SignalR服务,如下所示:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddSignalR(); // 添加SignalR服务
}

这样就完成了SignalR服务的添加。接下来在Configure方法中添加SignalR中间件,并添加Hub映射。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // 省略其他代码
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapHub<MessageHub>("/message"); // 添加Hub映射
    });
}

步骤二: 创建一个Hub

SignalR的核心组件是Hub,它负责维护客户端与服务端之间的连接和消息传递。在服务器端,我们需要创建一个继承自Hub的类,如下所示:

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

这是一个简单的Hub,其中有一个叫做SendMessage的方法,当客户端调用这个方法时,会收到来自服务端的回调消息,调用Clients.All.SendAsync方法广播消息给所有客户端。

步骤三: 在客户端订阅Hub

在客户端,我们需要调用SignalR客户端库中的方法订阅Hub的事件。

首先在html页面中添加SignalR客户端库的引用。我们可以通过CDN或本地文件引用这个库,这里我们使用CDN引用:

<script src="https://cdn.jsdelivr.net/npm/@microsoft/signalr@3.1.1/dist/browser/signalr.min.js"></script>

接下来在JavaScript中初始化SignalR连接:

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/message")
    .build();

其中,withUrl方法接受一个url参数,表示服务端的Hub地址。

接着,在SignalR连接成功之后,我们需要订阅服务端的事件,如下所示:

connection.on("ReceiveMessage", (user, message) => {
    console.log(`[${user}] ${message}`);
});

这里我们订阅了服务端的“ReceiveMessage”事件,并在这个事件发生时,打印收到的消息。

步骤四: 发送消息并接收回调

最后,我们可以通过SignalR连接对象调用服务端中的方法来发送消息:

const user = "John";
const message = "Hello, SignalR!";

connection.invoke("SendMessage", user, message);

这里我们调用了服务端的SendMessage方法,将用户名和消息内容作为参数传递给服务端。

当服务端收到这个方法调用时,会广播一条消息给所有客户端,客户端会在前面的步骤中订阅到这个消息事件,并调用对应的回调函数。

示例一: 使用SignalR实现聊天室功能

以上是SignalR的基本使用方法,我们可以将其应用到实际的项目中。下面我们来看一个使用SignalR实现聊天室功能的示例:

Step1: 创建一个ChatHub

在服务器端创建一个ChatHub,实现客户端和服务端之间的消息传递。示例代码如下:

public class ChatHub : Hub
{
    public async Task SendMessage(User user, string message)
    {
        var currentUser = Context.User.Identity.Name;
        await Clients.All.SendAsync("ReceiveMessage", currentUser, message);
    }

    public async override Task OnConnectedAsync()
    {
        await base.OnConnectedAsync();

        var currentUser = Context.User.Identity.Name;
        Clients.AllExcept(Context.ConnectionId).SendAsync("UserConnected", currentUser);
    }

    public async override Task OnDisconnectedAsync(Exception ex)
    {
        await base.OnDisconnectedAsync(ex);

        var currentUser = Context.User.Identity.Name;
        Clients.AllExcept(Context.ConnectionId).SendAsync("UserDisconnected", currentUser);
    }
}

在这个Hub中,我们实现了三个方法:SendMessage、OnConnectedAsync和OnDisconnectedAsync。

SendMessage 方法在收到客户端的消息后,将消息广播给所有客户端。

OnConnectedAsync 和 OnDisconnectedAsync 方法在客户端连接和断开连接时会被自动调用,在这里我们可以实现一些自定义的逻辑,比如广播用户上下线消息。

Step2: 创建一个聊天页面

创建一个聊天页面,向用户展示在线用户列表、聊天消息列表和聊天输入框。示例代码如下:

<div id="chat">
    <div id="user-list"></div>

    <hr />

    <div id="message-list"></div>

    <hr />

    <div>
        <input type="text" id="message-input" />
        <button id="send-button">发送</button>
    </div>
</div>

Step3: 初始化SignalR连接

在JavaScript中,我们需要初始化SignalR连接,并订阅服务端的“ReceiveMessage”、“UserConnected”和“UserDisconnected”事件,以便在收到消息时更新UI界面:

window.onload = function() {
    const chat = document.getElementById("chat");

    const connection = new signalR.HubConnectionBuilder()
        .withUrl("/chat")
        .build();

    connection.on("ReceiveMessage", (user, message) => {
        const messageList = document.getElementById("message-list");
        const messageItem = document.createElement("div");
        messageItem.innerText = `[${user}] ${message}`;
        messageList.appendChild(messageItem);
    });

    connection.on("UserConnected", (user) => {
        const userList = document.getElementById("user-list");
        const userItem = document.createElement("div");
        userItem.innerText = user;
        userList.appendChild(userItem);
    });

    connection.on("UserDisconnected", (user) => {
        const userList = document.getElementById("user-list");
        for (let i = 0; i < userList.childElementCount; i++) {
            const userItem = userList.children[i];
            if (userItem.innerText === user) {
                userList.removeChild(userItem);
                return;
            }
        }
    });

    connection.start().then(() => {
        const username = prompt("请输入您的用户名:");
        chat.style.display = "block";
        connection.invoke("AddUser", username);
    });

    const sendButton = document.getElementById("send-button");
    const messageInput = document.getElementById("message-input");
    sendButton.addEventListener("click", (event) => {
        const message = messageInput.value;
        messageInput.value = "";
        connection.invoke("SendMessage", message);
    });
};

在这个JavaScript代码中,我们创建了一个连接对象,并订阅了服务端的“ReceiveMessage”、“UserConnected”和“UserDisconnected”事件。

在连接成功之后,我们会让用户输入用户名,并调用服务端的AddUser方法将用户加入聊天室。

点击发送按钮时会调用SendMessage方法,将用户输入的消息发送给服务端进行广播。

示例二: 使用SignalR实现实时通知功能

第二个示例是使用SignalR实现一个实时通知功能。具体实现过程如下:

Step1: 创建一个NotifyHub

在服务器端创建一个NotifyHub,实现客户端和服务端之间的消息传递。示例代码如下:

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

在这个Hub中,我们实现了一个SendMessage方法,当服务端收到这个方法调用时,会广播一条消息给所有客户端。

Step2: 添加一个NotifyController

创建一个NotifyController,用于处理前端发送的HTTP请求。示例代码如下:

[ApiController]
[Route("[controller]/[action]")]
public class NotifyController : ControllerBase
{
    private readonly IHubContext<NotifyHub> _hubContext;

    public NotifyController(IHubContext<NotifyHub> hubContext)
    {
        _hubContext = hubContext;
    }

    [HttpPost]
    public async Task<IActionResult> Post([FromBody] NotifyRequest request)
    {
        await _hubContext.Clients.All.SendAsync("ReceiveMessage", request.Message);
        return Ok();
    }
}

public record NotifyRequest(string Message);

在这个Controller中,我们注入了一个IHubContext对象,用于向客户端发送实时通知。

同时,我们添加了一个HTTP Post方法,用于处理前端发送的请求。在这个方法中,我们调用_hubContext.Clients.All.SendAsync方法广播消息给所有客户端。

Step3: 前端页面代码

最后,我们在前端页面中添加一个按钮,点击按钮时会向服务端发送一个HTTP Post请求,从而触发实时通知。示例代码如下:

<div>
    <button id="notify-button">发送通知</button>
</div>

<script>
    const notifyButton = document.getElementById("notify-button");
    notifyButton.addEventListener("click", (event) => {
        fetch("/Notify/Post", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify({
                message: "这是一条实时通知!"
            })
        });
    });
</script>

在这个JavaScript代码中,我们添加了一个点击事件处理程序,当用户点击“发送通知”按钮时,向服务端发送一个HTTP Post请求,携带通知消息。

至此,我们就完成了使用SignalR实现实时通知功能的示例。

通过上面的两个示例可以清晰了解如何在Asp.net core中使用SignalR推送消息的过程和方法,并通过实例演示实现了聊天室和实时通知的功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Asp.net core 使用SignalR推送消息过程详解 - Python技术站

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

相关文章

  • C#解决多IfElse判断语句和Switch语句问题的方法分享

    下面是详细讲解“C#解决多IfElse判断语句和Switch语句问题的方法分享”的完整攻略: 介绍 在编写C#程序时,经常会遇到需要根据特定的条件确定应该执行哪些代码的情况。在很多情况下,我们可能需要写出许多的if-else语句或switch语句来实现这一功能。 然而,当条件判断较多时,if-else语句或switch语句的嵌套就会变得越来越复杂,代码越来越…

    C# 2023年6月7日
    00
  • 使用 BenchmarkDotNet 对 C# 代码进行基准测试

    以下是使用 BenchmarkDotNet 对 C# 代码进行基准测试的完整攻略。 什么是 BenchmarkDotNet? BenchmarkDotNet 是一个用于 .NET 应用程序的基准测试框架。它允许你轻松地编写、运行和分析基准测试代码,以衡量代码性能和稳定性,从而帮助你做出优化决策。 如何使用 BenchmarkDotNet 进行基准测试? 首先…

    C# 2023年6月3日
    00
  • Asp.Net Core配置多环境log4net配置文件的全过程

    下面是详细讲解”Asp.Net Core配置多环境log4net配置文件的全过程”的完整攻略: 1. 引入log4net依赖 可以通过Nuget包管理器或手动安装的方式引入log4net,以Nuget包管理器为例,可以在项目中右键点击“管理NuGet程序包”,然后搜索log4net安装即可。 2. 配置log4net log4net的配置文件可以放置在多个环…

    C# 2023年6月3日
    00
  • C# WinForm捕获全局变量异常 SamWang解决方法

    下面是详细讲解“C# WinForm捕获全局变量异常SamWang解决方法”的完整攻略。 背景 在C# WinForm程序的开发过程中,如果出现了全局变量异常,这会导致程序崩溃或者无法正常运行。为了避免这种情况的发生,我们需要在程序中加入一些对全局变量异常的处理方法。 解决方法 一般来说,我们可以使用try-catch语句来捕获全局变量异常。但是,如果全局变…

    C# 2023年5月14日
    00
  • 浅谈C# 序列化与反序列化几种格式的转换

    下面是 “浅谈C# 序列化与反序列化几种格式的转换” 的完整攻略: 目录 什么是序列化与反序列化 为什么需要序列化与反序列化 C# 中实现序列化与反序列化的几种方式 XML 序列化与反序列化 JSON 序列化与反序列化 Binary 序列化与反序列化 示例说明 XML 序列化与反序列化示例 JSON 序列化与反序列化示例 什么是序列化与反序列化 序列化(Se…

    C# 2023年5月31日
    00
  • C#调用C++ DLL bool返回值始终为true的问题

    下面是详细的C#调用C++ DLL bool返回值始终为true的解决攻略: 问题描述 在C#调用C++ DLL的过程中,如果C++ DLL返回bool值,而在C#程序中bool返回值始终为true,这是因为bool在C++和C#中的实现方式有所不同,C++中的bool通常占用1个字节,而C#中的bool占用4个字节,在C#中bool类型值为0时,对应的是-…

    C# 2023年6月6日
    00
  • asp.net显示自己的网页图标的几种方式

    下面是“ASP.NET显示自己的网页图标的几种方式”的详细讲解,包括两个示例说明。 方式一:在HTML中引入favicon 在HTML页面的<head>标签中添加如下代码: <link rel="shortcut icon" href="/favicon.ico" type="image/x…

    C# 2023年6月3日
    00
  • ASP.NET Core中Razor页面与MVC区别介绍

    ASP.NET Core中Razor页面与MVC区别介绍 ASP.NET Core是一个跨平台的开源框架,它可以帮助我们构建高性能的Web应用程序。在ASP.NET Core中,我们可以使用Razor页面和MVC来构建Web应用程序。本攻略将详细介绍Razor页面和MVC的区别,并提供两个示例说明。 Razor页面 Razor页面是一种基于HTML的视图引擎…

    C# 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部