JS+AbpVnext实现SignalR通信

2 篇文章 0 订阅
1 篇文章 0 订阅

💡 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.效果如下:

添加到指定分组后,将消息发送到该分组所有客户端中

image.png

(未解决)问题描述:

根据Abp Vnext官方文档中介绍,我添加了“AbpAspNetCoreSignalRModule”,所以可以不使用
services.AddSignalR() 和 app.UseEndpoints(…),它们在 AbpAspNetCoreSignalRModule 中已经添加了.
当我不使用它们时,我的客户端连接不上服务端。

先看Abp上的文档:
官网原文截图:
image.png
image.png
方式1(未成功)
步骤:

  • 在我的Module中将以下代码注释:
services.AddSignalR().AddJsonProtocol(options =>
                        {
                            //将序列化程序配置为不更改属性名称的大小写,但又不使用默认的大小写名称
                            options.PayloadSerializerOptions.PropertyNamingPolicy = null;
                        });
app.UseEndpoints(endpoints =>
        {
            endpoints.MapHub<BiddingSignalRHub>("/bidding-signalr-hub");
        });
  • 将JavaScript客户端中的路由改成“/signalr-hubs/biddingsignalr”
  • 预期效果,连接成功。
  • 实际结果如下:

image.png
方式2(未成功)
步骤:
和“方式1”一样,先将我自己的Module中的 “app.UseEndpoints()” 和 “services.AddSignalR()” 注释掉。
然后使用“[HubRoute(“/bidding-signalr-hub”)]”。

  • 预期效果,连接成功。
  • 实际结果如下

image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晒黑的绵羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值