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技术站