💡 SignalR通信:
使用JavaScript作为客户端,Abp Vnext作为服务端
成功案例(步骤):
1.引用“Volo.Abp.AspNetCore.SignalR” Nuget包
2.创建名为 BiddingSignalRHub.cs 的Hub类,继承自 AbpHub
public class BiddingSignalRHub : AbpHub
{
/// <summary>
/// 添加到分组
/// </summary>
/// <param name="groupName"></param>
/// <returns></returns>
public async Task AddToGroup(string groupName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
}
/// <summary>
/// 发送消息到指定分组
/// </summary>
/// <param name="groupName"></param>
/// <param name="message"></param>
/// <returns></returns>
public async Task SendMessageToGroup(string groupName, string message)
{
await Clients.Group(groupName).SendAsync("ReceiveMessage", message);
}
/// <summary>
/// 心跳检测用于前端判断是否重连
/// </summary>
/// <returns></returns>
public Task Heartbeat()
{
// 心跳检测成功,返回空响应
return Task.CompletedTask;
}
}
3.在你自己的“Module”文件中引用“AbpAspNetCoreSignalRModule” 并添加中间件中添加SignalR配置
[DependsOn(
typeof(AbpAspNetCoreSignalRModule)
)]
public class YourModule:AbpModule
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR().AddJsonProtocol(options =>
{
//将序列化程序配置为不更改属性名称的大小写,但又不使用默认的大小写名称
options.PayloadSerializerOptions.PropertyNamingPolicy = null;
});
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<BiddingSignalRHub>("/bidding-signalr-hub");
});
}
}
4.在客户端的HTML文件中引入SignalR库以及编写和JavaScript代码
html:
<!DOCTYPE html>
<html>
<head>
<title>SignalR Test</title>
</head>
<body>
<input type="text" id="txtMessage" placeholder="消息" />
<input type="text" id="txtGroup" placeholder="组名" />
<button onclick="sendMessage()">发送</button>
<button id="addToGroupButton">添加到组</button>
<div id="messageContainer"></div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/5.0.14/signalr.min.js"></script>
<script src="./js/signalr-client.js"></script>
</body>
</html>
JavaScript:(signalr-client.js 文件)
//建立连接
var connection = new signalR.HubConnectionBuilder().withUrl("https://localhost:44335/bidding-signalr-hub")
.withAutomaticReconnect(2000)
.build();
// 接收服务端发送的消息
connection.on("ReceiveMessage", function(message) {
// 处理接收到的消息
console.log("内容: " + message);
var messageContainer = document.getElementById("messageContainer");
var newMessage = document.createElement("p");
newMessage.textContent = message;
messageContainer.appendChild(newMessage);
});
// 启动连接
startConnection();
// 启动定期发送心跳检测
setInterval(sendHeartbeat, 500); // 每0.5秒发送一次心跳检测
// 尝试启动连接
function startConnection() {
connection.start()
.then(() => {
console.log("连接成功");
})
.catch((error) => {
console.error("连接失败:" + error);
});
}
// 定期发送心跳检测
function sendHeartbeat() {
connection.invoke("Heartbeat")
.then((result) => {
console.log("心跳检测成功");
})
.catch((error) => {
console.error("心跳检测失败:" + error);
connection.stop();
startConnection();
});
}
//发送消息到服务端
function sendMessage() {
var message = document.getElementById("txtMessage").value;
var groupName = document.getElementById("txtGroup").value; // 修改为要加入的组名
connection.invoke("SendMessageToGroup", groupName, message)
.then(function() {
console.log("已发送到分组:" + groupName);
})
.catch(function(error) {
console.error(error);
});
}
// 点击添加到组
document.getElementById("addToGroupButton").addEventListener("click", function() {
var groupName = document.getElementById("txtGroup").value; // 修改为要加入的组名
connection.invoke("AddToGroup", groupName)
.then(function() {
console.log("Added to group: " + groupName);
})
.catch(function(error) {
console.error(error);
});
});
5.效果如下:
添加到指定分组后,将消息发送到该分组所有客户端中
(未解决)问题描述:
根据Abp Vnext官方文档中介绍,我添加了“AbpAspNetCoreSignalRModule”,所以可以不使用
services.AddSignalR() 和 app.UseEndpoints(…),它们在 AbpAspNetCoreSignalRModule 中已经添加了.
当我不使用它们时,我的客户端连接不上服务端。
先看Abp上的文档:
官网原文截图:
方式1(未成功)
步骤:
- 在我的Module中将以下代码注释:
services.AddSignalR().AddJsonProtocol(options =>
{
//将序列化程序配置为不更改属性名称的大小写,但又不使用默认的大小写名称
options.PayloadSerializerOptions.PropertyNamingPolicy = null;
});
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<BiddingSignalRHub>("/bidding-signalr-hub");
});
- 将JavaScript客户端中的路由改成“/signalr-hubs/biddingsignalr”
- 预期效果,连接成功。
- 实际结果如下:
方式2(未成功)
步骤:
和“方式1”一样,先将我自己的Module中的 “app.UseEndpoints()” 和 “services.AddSignalR()” 注释掉。
然后使用“[HubRoute(“/bidding-signalr-hub”)]”。
- 预期效果,连接成功。
- 实际结果如下