ASP.NET Core SignalR (十)【上】:SignalR Javascript 客户端
此为系列文章,对MSDN ASP.NET Core SignalR 的官方文档进行系统学习与翻译。其中或许会添加本人对 ASP.NET Core 的浅显理解
ASP.NET Core SignalR Javascript 客户端类库使得开发者可以在Javascript代码中调用服务端的 中心(hub) 代码。
安装SignalR 客户端包
SignalR 客户端库是作为一个npm 包被传送的。如果你正在使用Visual Studio,在root 文件夹中,从包管理器控制台(PMC)中运行 npm install 命令。而对于Visual Studio Code,从整合终端来运行如下命令:
npm init -y
npm install @microsoft/signalr
npm 将包内容安装到 node_modules\@microsoft\signalr\dist\browser 文件夹。在 wwwroot\lib 文件夹下新建一个名为 signalr 的文件夹。将 signalr.js 文件拷贝到 wwwroot\lib\signalr 文件夹。
使用SignalR Javascript 客户端
在 <script>元素中引用SignalR Javascript客户端。
<script src="~/lib/signalr/signalr.js"></script>
连接到一个 中心(hub)
以下代码创建并开启了一个连接。Hub的名称是大小写不敏感的。
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chatHub")
.configureLogging(signalR.LogLevel.Information)
.build();
start();
/* this is here to show an alternative to start, with a then
跨越连接
一般来说,浏览器加载来自于相同域的连接作为请求页。然而,也有一些情形我们需要连接到另一个域。
为了阻止恶意站点从另一个站点读取敏感数据,默认情况下,cross-origin connections 会被禁掉。为了允许跨域请求,可以在Startup 类中启用它。
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using SignalRChat.Hubs; namespace SignalRChat { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddMvc(); services.AddCors(options => options.AddPolicy("CorsPolicy", builder => { builder.AllowAnyMethod().AllowAnyHeader() .WithOrigins("http://localhost:55830") .AllowCredentials(); })); services.AddSignalR(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseBrowserLink(); app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseCors("CorsPolicy"); app.UseSignalR(routes => { routes.MapHub<ChatHub>("/chathub"); }); app.UseMvc(); } } }
从客户端调用 中心 方法
Javascript 客户端通过HubConnection的 invoke 方法来调用 中心 定义的 public 方法。 invoke 方法接收两个参数:
- 中心 方法的名称。在如下的示例中,中心的方法名称是SendMessage。
- 定义在 中心 方法中的任意参数。在如下的示例中,参数名称是message。如下的代码示例使用了箭头函数标记,其在除IE之外的所以主流浏览器的当前版本中都会支持。
connection.invoke("SendMessage", user, message).catch(err => console.error(err.toString()));
注意:如果你正在以无服务模式使用Azure SignalR 服务,你将不能从客户端调用 中心 方法。更多信息,请参考SignalR Service documentation。
invoke
方法返回一个Javascript Promise。当服务端的方法返回时,使用返回值(如果有)对Promise
进行解析。如果服务端的方法抛出了一个错误,Promise
就会用错误信息被拒绝。在Promise 本身使用 then 和 catch方法以处理这些情形(或者await 标记)。
send 方法返回一个Javascript Promise。当消息被送到服务器时,Promise会被解析。如果消息的发送过程中产生了一个错误,Promise便会以此错误消息被拒绝。使用Promise本身的 then 和 catch 方法来处理这些情形(或者await标记)。
注意,使用send 不会等到服务端接收到消息。因此,从服务端返回数据或者错误是不可能的。
从 中心 调用客户端的方法
为了接收从 中心 发送的消息,我们可以使用 HubConnection 的 on来定义一个方法。
- Javascript客户端方法的名称。在如下的示例中,方法的名称是ReceiveMessage。
- 中心 传递给方法的参数。在如下的示例中,参数值是 message。
connection.on("ReceiveMessage", (user, message) => { const encodedMsg = user + " says " + message; const li = document.createElement("li"); li.textContent = encodedMsg; document.getElementById("messagesList").appendChild(li); });
如上在connection.on 中定义了一个方法。当服务端代码通过 SendAsync 来调用它的时候,它将会运行。
public async Task SendMessage(string user, string message) { await Clients.All.SendAsync("ReceiveMessage", user, message); }
通过匹配定义在SendAsync
和 connection.on 中的方法名称和参数,SignalR决定了哪一个客户端方法将会被调用。
注意,作为一个最佳实践,在HubConnection上在on 之后调用start 方法。这样做可以确保你的处理器在任何消息被接收之前就已进行注册。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南