signalR

## 创建 Web 应用项目

- [Visual Studio](https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-6.0&tabs=visual-studio#tabpanel_2_visual-studio)
- [Visual Studio Code](https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-6.0&tabs=visual-studio#tabpanel_2_visual-studio-code)
- [Visual Studio for Mac](https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-6.0&tabs=visual-studio#tabpanel_2_visual-studio-mac)

- 从菜单中选择“文件”>“新建项目”。
- 在“创建新项目”对话框中,选择“ASP.NET Core Web 应用程序”,然后选择“下一步” 。
- 在“配置新项目”对话框中,将项目命名为“SignalRChat”,然后选择“创建”。
- 在“创建新的 ASP.NET Core Web 应用程序”对话框中,选择 .NET Core 和 ASP.NET Core 3.1 。
- 选择“Web 应用程序”以创建使用 Razor Pages 的项目,然后选择“创建” 。

![Visual Studio 中的“新建项目”对话框](https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr/_static/3.x/signalr-new-project-dialog.png?view=aspnetcore-6.0)

## 添加 SignalR 客户端库

ASP.NET Core 3.1 共享框架中包含 SignalR 服务器库。 JavaScript 客户端库不会自动包含在项目中。 对于此教程,使用库管理器 (LibMan) 从 unpkg 获取客户端库。 unpkg 是一个内容分发网络 (CDN),可分发在 npm(即 Node.js 包管理器)中找到的任何内容。

- [Visual Studio](https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-6.0&tabs=visual-studio#tabpanel_3_visual-studio)
- [Visual Studio Code](https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-6.0&tabs=visual-studio#tabpanel_3_visual-studio-code)
- [Visual Studio for Mac](https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-6.0&tabs=visual-studio#tabpanel_3_visual-studio-mac)

- 在“解决方案资源管理器”中,右键单击项目,然后选择“添加”>“客户端库” 。
- 在“添加客户端库”对话框中,对于“提供程序”,选择“unpkg”。
- 对于“库”,输入 `@microsoft/signalr@latest`。
- 选择“选择特定文件”,展开“dist/browser”文件夹,然后选择“signalr.js”和“signalr.min.js”。
- 将“目标位置”设置为 wwwroot/js/signalr/,然后选择“安装”。

![“添加客户端库”对话框 - 选择库](https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr/_static/3.x/find-signalr-client-libs-select-files.png?view=aspnetcore-6.0)

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

## 创建 SignalR 中心

*中心* 是一个类,用作处理客户端 - 服务器通信的高级管道。

- 在 SignalRChat 项目文件夹中,创建 Hubs 文件夹。
- 在 Hubs 文件夹中,使用以下代码创建 ChatHub.cs 文件 :

C#复制

```csharp
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

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

`ChatHub` 类继承自 SignalR `Hub` 类。 `Hub` 类管理连接、组和消息。

可通过已连接客户端调用 `SendMessage`,以向所有客户端发送消息。 本教程后面部分将显示调用该方法的 JavaScript 客户端代码。 SignalR 代码是异步模式,可提供最大的可伸缩性。

## 配置 SignalR

必须将 SignalR 服务器配置为将 SignalR 请求传递给 SignalR。

- 将以下突出显示的代码添加到 Startup.cs 文件。

C#复制

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SignalRChat.Hubs;

namespace SignalRChat
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddSignalR();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapHub<ChatHub>("/chatHub");
});
}
}
}
```

这些更改将 SignalR 添加到 ASP.NET Core 依赖关系注入和路由系统。

## 添加 SignalR 客户端代码

- 使用以下代码替换 Pages\Index.cshtml 中的内容:

CSHTML复制

```cshtml
@page
<div class="container">
<div class="row">&nbsp;</div>
<div class="row">
<div class="col-2">User</div>
<div class="col-4"><input type="text" id="userInput" /></div>
</div>
<div class="row">
<div class="col-2">Message</div>
<div class="col-4"><input type="text" id="messageInput" /></div>
</div>
<div class="row">&nbsp;</div>
<div class="row">
<div class="col-6">
<input type="button" id="sendButton" value="Send Message" />
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<hr />
</div>
</div>
<div class="row">
<div class="col-6">
<ul id="messagesList"></ul>
</div>
</div>
<script src="~/js/signalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>
```

前面的代码:

- 创建名称以及消息文本的文本框和“提交”按钮。
- 使用 `id="messagesList"` 创建一个列表,用于显示从 SignalR 中心接收的消息。
- 包含对 SignalR 的脚本引用以及在下一步中创建的“chat.js”应用程序代码。

- 在 wwwroot/js 文件夹中,使用以下代码创建 chat.js 文件 :

JavaScript复制

```javascript
"use strict";

var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

//Disable send button until connection is established
document.getElementById("sendButton").disabled = true;

connection.on("ReceiveMessage", function (user, message) {
var li = document.createElement("li");
document.getElementById("messagesList").appendChild(li);
// We can assign user-supplied strings to an element's textContent because it
// is not interpreted as markup. If you're assigning in any other way, you
// should be aware of possible script injection concerns.
li.textContent = `${user} says ${message}`;
});

connection.start().then(function () {
document.getElementById("sendButton").disabled = false;
}).catch(function (err) {
return console.error(err.toString());
});

document.getElementById("sendButton").addEventListener("click", function (event) {
var user = document.getElementById("userInput").value;
var message = document.getElementById("messageInput").value;
connection.invoke("SendMessage", user, message).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
});
```

前面的代码:

- 创建并启动连接。
- 向“提交”按钮添加一个用于向中心发送消息的处理程序。
- 向连接对象添加一个用于从中心接收消息并将其添加到列表的处理程序。

 

posted @ 2022-03-07 17:31  wolfsocket  阅读(120)  评论(0编辑  收藏  举报