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# Stream 和 byte[] 之间的转换

    在C#中,Stream和byte[]是常用的数据类型,用于读取和写入数据。本文将提供详细的“C#Stream和byte[]之间的转换”的完整攻略,包括如何将Stream转换为byte[],以及如何将byte[]转换为Stream。同时,本文还将提供两个示例,以帮助读者更好地理解如何在C#中进行Stream和byte[]之间的转换。 将Stream转换为byt…

    C# 2023年5月15日
    00
  • ASP.NET Core使用功能开关控制路由访问操作

    ASP.NET Core使用功能开关控制路由访问操作 在ASP.NET Core应用程序中,我们可以使用功能开关来控制路由访问操作。功能开关是一种机制,可以在应用程序中启用或禁用特定的功能。在本文中,我们将介绍如何使用功能开关来控制路由访问操作,并提供一些示例来说明如何使用它们。 安装Microsoft.FeatureManagement.AspNetCor…

    C# 2023年5月17日
    00
  • 如何利用C#正则表达式判断是否是有效的文件及文件夹路径

    C#中正则表达式可以用来匹配、搜索、替换字符串等操作,因此可以用来判断一个字符串是否符合文件或文件夹路径的格式。下面是利用C#正则表达式判断是否是有效的文件及文件夹路径的攻略。 一、正则表达式 下面是表示文件路径的正则表达式: ^[a-zA-Z]:\\[^*?"<>|]+\.[^*?"<>|]+$ 下面是表示文件夹…

    C# 2023年5月15日
    00
  • .NET Core下使用Log4Net记录日志的方法步骤

    .NET Core下使用Log4Net记录日志的方法步骤 Log4Net是一个流行的日志记录框架,可以在.NET Core应用程序中使用。本攻略将介绍如何在.NET Core应用程序中使用Log4Net记录日志,并提供两个示例说明。 步骤一:安装Log4Net 在.NET Core应用程序中使用Log4Net,需要先安装Log4Net。可以按照以下步骤操作:…

    C# 2023年5月16日
    00
  • C#滚动字幕的实现方法

    下面是关于“C#滚动字幕的实现方法”的详细攻略: 实现思路 滚动字幕的实现思路,主要是通过定时器控制文字的位置,达到滚动的效果。在具体实现的过程中,需要使用 C# 的画布 (System.Drawing.Graphics) 绘制文字,以及使用 System.Windows.Forms.Timer 控制滚动的速度。 实现步骤 1. 创建一个窗体 通过 Visu…

    C# 2023年6月3日
    00
  • 如何在C# 中查找或结束程序域中的主、子进程

    如何在C# 中查找或结束程序域中的主、子进程 在C#中可以使用Process类来查找、启动和结束进程。Process类封装了与操作系统进程相关的一些API,并提供了简便的方法来管理和控制进程。以下是有关如何在C#中查找或结束程序域中主、子进程的攻略: 查找主进程 首先,我们要通过获取当前进程的进程ID,来查找主进程。在C#中,可以使用 Process.Get…

    C# 2023年6月6日
    00
  • C#中让控件全屏显示的实现代码(WinForm)

    以下是C#中让控件全屏显示的实现代码的攻略: 第一步:准备工作 首先,在你的WinForm程序中找到需要全屏显示的控件(例如一个PictureBox),然后在窗体的SizeChanged事件中添加代码。 接下来,你需要给控件添加以下属性: Dock = Fill 使得控件充满整个窗体 Anchor = Top, Bottom, Left, Right 使得控…

    C# 2023年6月7日
    00
  • c#3.0实现延迟赋值示例

    下面我详细讲解一下“C#3.0实现延迟赋值示例”的完整攻略。 什么是延迟赋值 延迟赋值就是指将变量的赋值操作推迟到该变量首次被访问时再执行。这种赋值方式可以有效地减少不必要的计算和内存开销,提高程序的运行效率。 C#3.0如何实现延迟赋值 在C#3.0中,可以使用lazy关键字和Lazy<T>类来实现延迟赋值。 当声明一个变量时,可以在变量前加上…

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