ASP.NET Core SignalR 系列(三)- JavaScript 客户端

这篇具有很好参考价值的文章主要介绍了ASP.NET Core SignalR 系列(三)- JavaScript 客户端。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本章将和大家分享 ASP.NET Core SignalR 中的 JavaScript 客户端。ASP.NET Core SignalR JavaScript 客户端库使开发人员能够调用服务器端SignalR中心代码。

本文大部分内容摘自微软官网:https://learn.microsoft.com/zh-cn/aspnet/core/signalr/javascript-client?view=aspnetcore-7.0&tabs=visual-studio

废话不多说,下面我们直接进入本章主题: 

1、安装 SignalR 客户端包

ASP.NET Core 共享框架中包含 SignalR 服务器库。JavaScript 客户端库不会自动包含在项目中。对于此教程,使用库管理器 (LibMan) 从 unpkg 获取客户端库。unpkg 是一个快速的全局内容分发网络,适用于 npm 上的所有内容。

在 Visual Studio “解决方案资源管理器” 中,右键单击项目,然后选择 “添加” => “客户端库”。

在“添加客户端库”对话框中:

  • 为“提供程序”选择“unpkg”。
  • 对于“库”,请输入 @microsoft/signalr@latest。
  • 选择“选择特定文件”,展开“dist/browser”文件夹,然后选择 signalr.js 和 signalr.min.js。
  • 将“目标位置”设置为 wwwroot/js/signalr/。(可根据实际情况进行修改)
  • 选择“安装” 。

ASP.NET Core SignalR 系列(三)- JavaScript 客户端

LibMan 会创建 wwwroot/js/signalr 文件夹并将所选文件复制到该文件夹下。

2、连接到中心

以下代码创建并启动连接。中心的名称不区分大小写:

//第一个参数:加载依赖模块,可以是require_config中定义的短模块名,也可以是完整的模块路径(去掉.js后缀名,根目录为require_config中设置的baseUrl)
//第二个参数:执行加载完后的回调函数
require(['../common/base', 'jquery', 'signalr'], function (base, $, signalR) {
    let axios = base.axios;

    var vm = new base.vue({
        el: '#app', //挂载点
        mixins: [base.mixin], //混入,类似基类的概念
        data: {
            connectionSignalR: '', //SignalR连接
            user: '',
            message: '',
            msgList: []
        },
        //created钩子函数
        created: function () {
            this.initSignalR(); //初始化SignalR
        },
        //mounted钩子函数
        mounted: function () {
            //console.log('This is index mounted');
        },
        //方法
        methods: {
            //初始化SignalR
            initSignalR: function () {
                var _this = this;
                var domain = "http://localhost:5296"; //网站域名

                //创建连接
                _this.connectionSignalR = new signalR.HubConnectionBuilder()
                    .withUrl(domain + "/chatHub") //跨域的话必须使用绝对路径
                    .configureLogging(signalR.LogLevel.Error) //配置日志等级
                    //自动重新连接,尝试每次重新连接之前默认分别等待 0、2、10 和 30 秒。尝试四次失败后,它会停止尝试重新连接。
                    .withAutomaticReconnect() //.withAutomaticReconnect([0, 2000, 10000, 30000]) 
                    .build();
                /*
                    日志等级:
                    signalR.LogLevel.Error:错误消息。 Error仅记录消息。
                    signalR.LogLevel.Warning:有关潜在错误的警告消息。 日志 Warning 和 Error 消息。
                    signalR.LogLevel.Information:无错误的状态消息。 日志 Information 、 Warning 和 Error 消息。
                    signalR.LogLevel.Trace:跟踪消息。 记录所有内容,包括中心和客户端之间传输的数据。
                */

                //监听中心(服务端)发送的消息(服务端调用客户端)(订阅)
                //ReceiveMessage 是服务端调用客户端的方法名
                _this.connectionSignalR.on("ReceiveMessage", function (user, message) {
                    _this.msgList.push({
                        user: user,
                        message: message
                    });
                });

                //启动连接
                _this.connectionSignalR.start().then(function () {
                    //启动连接后需要立即执行的逻辑
                    //document.getElementById("sendButton").disabled = false;
                }).catch(function (err) {
                    return console.error(err.toString());
                });
            },
            //发送消息
            sendMsg: function () {
                var _this = this;

                if (_this.message) {
                    //向中心(服务端)发送消息(客户端调用服务端)
                    //SendMessage 是服务端定义的的方法
                    _this.connectionSignalR.invoke("SendMessage", _this.user, _this.message).catch(function (err) {
                        return console.error(err.toString());
                    });
                    _this.message = ''; //发送完清空消息
                }
            },
        }
    });
});

3、跨域连接(CORS)

通常,浏览器从与请求页面相同的域加载连接。但是,有时需要连接到另一个域。

发出跨域请求时,客户端代码必须使用绝对 URL 而不是相对 URL。对于跨域请求,需要将 .withUrl("/chathub") 修改为 .withUrl("https://{App domain name}/chathub") 。

为了防止恶意站点从另一站点读取敏感数据,默认情况下禁用跨域连接。若要允许跨源请求,请启用 CORS:

using SignalRChat.Hubs;

namespace SignalRChat
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            //服务注册(往容器中添加服务)
            // Add services to the container.
            builder.Services.AddControllersWithViews();
            builder.Services.AddSignalR(); //注册中心所需的 SignalR 服务

            //设置允许跨域
            builder.Services.AddCors(options =>
            {
                options.AddDefaultPolicy(
                    builder =>
                    {
                        builder.WithOrigins("http://localhost:5296", "http://localhost:8080")
                            .AllowAnyHeader()
                            .WithMethods("GET", "POST")
                            .AllowCredentials();
                    });
            });

            var app = builder.Build();

            //配置Http请求处理管道
            // Configure the HTTP request pipeline.
            if (!app.Environment.IsDevelopment())
            {
                app.UseExceptionHandler("/Home/Error");
            }
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            //设置允许跨域
            // UseCors must be called before MapHub. //必须在 MapHub 之前调用 UseCors 方法
            app.UseCors();

            //配置MVC路由
            app.MapControllerRoute(
                name: "areas",
                pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
            app.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");

            //配置SignalR终结点
            app.MapHub<ChatHub>("/chatHub"); //中心
            app.MapHub<StronglyTypedChatHub>("/stronglyTypedChatHub"); //强类型中心

            app.Run();
        }
    }
}

必须在 MapHub 之前调用 app.UseCors(); 方法。

4、从客户端调用中心方法

JavaScript 客户端通过 HubConnection 的 invoke 方法调用中心的公共方法。invoke 方法接受:

  • 中心方法的名称。
  • 中心方法中定义的任何参数。

在以下突出显示的代码中,中心上的方法名称为 SendMessage。传递到 invoke 的第二个和第三个参数映射到中心方法的 user 和 message 参数:

try {
    await connection.invoke("SendMessage", user, message);
} catch (err) {
    console.error(err);
}

仅在默认模式下使用 Azure SignalR 服务 时,才支持从客户端调用中心方法。

invoke 方法返回 JavaScript Promise。 服务器上的方法返回时,Promise 通过返回值(如果有)进行解析。如果服务器上的方法引发错误,Promise 会被拒绝并显示错误消息。使用 async 和 await 或 Promise 的 then 和 catch 方法来处理这些情况。

JavaScript 客户端还可以通过 HubConnection 的 send 方法调用中心的公共方法。与 invoke 方法不同,send 方法不会等待来自服务器的响应。send 方法返回 JavaScript Promise。当消息发送到服务器后,会解析 Promise。如果发送消息时出错,Promise 会被拒绝并显示错误消息。使用 async 和 await 或 Promise 的 then 和 catch 方法来处理这些情况。

使用 send 不会等到服务器收到消息。因此,无法从服务器返回数据或错误。

5、从中心调用客户端方法

若要接收来自中心的消息,请使用 HubConnection 的 on 方法定义方法:

  • JavaScript 客户端方法的名称。
  • 中心传递给方法的参数。

在下面的示例中,方法名称为 ReceiveMessage。参数名称为 user 和 message:

connection.on("ReceiveMessage", (user, message) => {
    const li = document.createElement("li");
    li.textContent = `${user}: ${message}`;
    document.getElementById("messageList").appendChild(li);
});

connection.on 中的上述代码在服务器端代码使用 SendAsync 方法调用它时运行:

using Microsoft.AspNetCore.SignalR;
namespace SignalRChat.Hubs;

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

SignalR 通过匹配在 SendAsync 和 connection.on 中定义的方法名称和参数来确定要调用的客户端方法。

客户端的最佳做法是在 on 之后 调用 HubConnection 的 start 方法。这样做可确保在收到任何消息之前注册处理程序。

6、错误处理和日志记录

使用 console.error 在客户端无法连接或发送消息时将错误输出到浏览器的控制台:

try {
    await connection.invoke("SendMessage", user, message);
} catch (err) {
    console.error(err);
}

在建立连接时,通过传递记录器和要记录的事件类型来设置客户端日志跟踪。可用的日志级别如下所示:

  • signalR.LogLevel.Error:错误消息。仅记录 Error 消息。
  • signalR.LogLevel.Warning:有关潜在错误的警告消息。记录 Warning 和 Error 消息。
  • signalR.LogLevel.Information:没有错误的状态消息。记录 Information、Warning 和 Error 消息。
  • signalR.LogLevel.Trace:跟踪消息。记录所有内容,包括在中心和客户端之间传输的数据。

使用 HubConnectionBuilder 上的 configureLogging 方法配置日志级别。消息将记录到浏览器控制台:

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .configureLogging(signalR.LogLevel.Information)
    .build();

7、重新连接客户端

1)自动重新连接

默认情况下,它不会自动重新连接。如果需要自动重新连接,则可以将  SignalR 的 JavaScript 客户端配置为使用 HubConnectionBuilder 上的 WithAutomaticReconnect 方法。

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

如果不使用任何参数,WithAutomaticReconnect 会将客户端配置为每次尝试重新连接之前分别等待 0、2、10 和 30 秒。尝试四次失败后,会停止尝试重新连接。

配置自定义的重新连接尝试次数,withAutomaticReconnect 会接受一个数字数组,表示在每次开始尝试重新连接之前要等待的延迟(以毫秒为单位):

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/chathub")
    .withAutomaticReconnect([0, 0, 10000])
    .build();

    // .withAutomaticReconnect([0, 2000, 10000, 30000]) yields the default behavior

若要更好地控制自动重新连接尝试的时间和次数,可以自行去微软官网了解。

2)手动重新连接

下面的代码演示典型的手动重新连接方法:

  1. 创建函数(在本例中为 start 函数)以启动连接。
  2. 在连接的 onclose 事件处理程序中调用 start 函数。
async function start() {
    try {
        await connection.start();
        console.log("SignalR Connected.");
    } catch (err) {
        console.log(err);
        setTimeout(start, 5000);
    }
};

connection.onclose(async () => {
    await start();
});

生产实现通常使用指数退避或重试指定的次数。

8、浏览器睡眠选项卡

某些浏览器具有选项卡冻结或休眠功能,用于减少非活动选项卡的计算机资源使用量。 这可能会导致 SignalR 连接关闭,并可能导致不必要的用户体验。

浏览器使用启发法判断选项卡是否应进入睡眠状态,下面的代码示例演示如何使用 Web Lock 将选项卡保持为唤醒状态,并避免意外的连接关闭:

var lockResolver;
if (navigator && navigator.locks && navigator.locks.request) {
    const promise = new Promise((res) => {
        lockResolver = res;
    });

    navigator.locks.request('unique_lock_name', { mode: "shared" }, () => {
        return promise;
    });
}

对于上述代码示例:

  • Web Lock 是实验性的。条件检查可确认浏览器是否支持 Web Lock。
  • 存储承诺解析程序 lockResolver,以便在选项卡进入睡眠状态时可以释放锁。
  • 关闭连接时,通过调用 lockResolver() 释放锁定。释放锁定时,选项卡可进入睡眠状态。

9、SignalR 信息推送的两种通道

1)客户端触发推送,如下所示:

ASP.NET Core SignalR 系列(三)- JavaScript 客户端

2)服务端触发推送,如下所示:

ASP.NET Core SignalR 系列(三)- JavaScript 客户端

至此本文就全部介绍完了,想要了解更多内容可参考微软官网。

 

Demo源码:

链接:https://pan.baidu.com/s/1U4IadFp-qThj0t3axrtNJA 
提取码:bwb3

此文由博主精心撰写转载请保留此原文链接:https://www.cnblogs.com/xyh9039/p/17539560.html

版权声明:如有雷同纯属巧合,如有侵权请及时联系本人修改,谢谢!!!文章来源地址https://www.toymoban.com/news/detail-556070.html

到了这里,关于ASP.NET Core SignalR 系列(三)- JavaScript 客户端的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ASP.NET Core SignalR 系列(四)- 中心筛选器

    本章将和大家分享 ASP.NET Core SignalR 中的中心筛选器。 本文大部分内容摘自微软官网:https://learn.microsoft.com/zh-cn/aspnet/core/signalr/hub-filters?view=aspnetcore-7.0 废话不多说,下面我们直接进入本章主题。 中心筛选器: 在 ASP.NET Core 5.0 或更高版本中可用。 允许在客户端调用中心方法之

    2024年02月16日
    浏览(27)
  • ASP.NET 获取客户端IP、MAC地址

      qqwry.dat 纯真IP数据库下载地址:   

    2024年02月15日
    浏览(35)
  • 服务端使用ASP.NET Core SignalR与Vue3(TypeScript与JavaScript)前端建立通信(以进度条为例)

    1. ASP.NET Core           ASP.NET Core 是一个跨平台、高性能及开源的框架,用于生成基于云且连接互联网的新式应用程式。 官方文档:ASP.NET documentation | Microsoft Learn  2.  ASP.NET Core SignalR         ASP.NET Core SignalR 是开源库,用于服务端与客户端建立实时通信,可以自动管理连接

    2024年02月06日
    浏览(36)
  • .net core WebAPI 获取客户端IP的地址

    1、写个扩展方法在控制器里面: 注:不能创建外部类,否则会报错,HttpContext必须是和带有继承ControllerBase的类一起才行 1.在Startup.cs文件里注入服务: 2、去控制器里面写入:

    2024年02月03日
    浏览(36)
  • ASP.NET Core SignalR 入门

    本章将和大家分享使用 SignalR 生成实时应用的基础知识。通过本文您将学习如何:使用ASP.NET Core SignalR + MVC + Vue 2.x + require 最终创建一个正常运行的简易聊天应用。 废话不多说,我们直接来看一个Demo,Demo的目录结构如下所示: 本Demo的Web项目为ASP.NET Core Web 应用程序( 目标框

    2024年02月11日
    浏览(31)
  • 什么是 ASP.NET Core SignalR?

    所有连接了 Internet 的应用程序都由服务器和客户端组成。 客户端依赖于服务器获取数据,而它们获取数据的主要机制是通过发出超文本传输协议 (HTTP) 请求来进行的。 某些客户端应用程序需要经常更改的数据。 ASP.NET Core SignalR 提供了一个 API,用于创建服务器到客户端远程过

    2024年02月15日
    浏览(23)
  • ASP.NET Core实时库SignalR简单应用

    SignalR 是用于构建需要实时用户交互或实时数据更新的Web 应用程序的一个开放源代码.NET 库。不仅仅用在Web应用中,后面会讲到它的应用范围。它简化了简化了构建实时应用程序的过程,包括 ASP.NET Server 库和 JavaScript Client 库,以便管理Client与Server连接并将内容更新推送给Cl

    2024年02月11日
    浏览(61)
  • ASP.NET Core+Vue3 实现SignalR通讯

    从ASP.NET Core 3.0版本开始,SignalR的Hub已经集成到了ASP.NET Core框架中。因此,在更高版本的ASP.NET Core中,不再需要单独引用Microsoft.AspNetCore.SignalR包来使用Hub。 在项目创建一个类继承Hub, 首先是写一个CreateConnection方法 ConnectionId是SignalR中标识的客户端连接的唯一标识符, 将userId和

    2024年02月06日
    浏览(34)
  • 【ASP.NET Core】使用SignalR推送服务器日志

    一个多月前接手了一个产线机器人项目,上位机以读写寄存器的方式控制机器人,服务器就是用 ASP.NET Core 写的 Web API。由于前一位开发者写的代码质量问题,导致上位机需要16秒才能启动。经过我近一个月的改造,除了保留业务逻辑代码,其他的基本重写。如今上位机的启动

    2024年02月03日
    浏览(43)
  • Web SSH 的原理与在 ASP.NET Core SignalR 中的实现

    有个项目,需要在前端有个管理终端可以 SSH 到主控机的终端,如果不考虑用户使用 vim 等需要在控制台内现实界面的软件的话,其实使用 Process 类型去启动相应程序就够了。而这次的需求则需要考虑用户会做相关设置。 这里用到的原理是伪终端。伪终端(pseudo terminal)是现

    2024年02月07日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包