You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求带可用WebSocket传输的ASP.NET Core 6+SignalR+Angular项目模板

ASP.NET Core 6 + Angular集成SignalR WebSocket的方案

现成项目模板说明

官方dotnet new angular模板并未预集成SignalR WebSocket,你可以通过两种方式获取可用模板:

  • 社区自定义模板:部分开发者会分享预配置好的模板,但版本可能存在滞后性,更可靠的方式是手动配置(下文重点说明)。
  • 自制模板:按照下文步骤配置好项目后,可通过dotnet new template命令将其打包为自定义模板,后续可直接调用使用。

手动配置步骤(解决WebSocket无法运行问题)

后端(ASP.NET Core 6)配置

  1. 安装SignalR包
    在项目根目录执行命令:
dotnet add package Microsoft.AspNetCore.SignalR
  1. 配置Program.cs
    需确保CORS、SignalR服务和中间件的顺序正确:
var builder = WebApplication.CreateBuilder(args);

// 添加SignalR服务
builder.Services.AddSignalR();
// 配置CORS,允许Angular客户端的WebSocket请求
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAngularClient", policy =>
    {
        policy.WithOrigins("http://localhost:4200") // 替换为你的Angular运行地址
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials(); // 必须开启,WebSocket请求需携带凭证
    });
});

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseRouting();

// 启用CORS,需放在UseRouting之后、UseAuthorization之前
app.UseCors("AllowAngularClient");

app.UseAuthorization();

// 映射默认路由
app.MapControllerRoute(
    name: "default",
    pattern: "{controller}/{action=Index}/{id?}");

// 映射SignalR Hub
app.MapHub<ChatHub>("/chatHub");

app.Run();
  1. 创建SignalR Hub类
    在项目中新建Hubs/ChatHub.cs:
using Microsoft.AspNetCore.SignalR;

namespace YourProjectNamespace.Hubs;

public class ChatHub : Hub
{
    // 示例:发送消息方法
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}

前端(Angular)配置

  1. 安装SignalR客户端包
    在ClientApp目录执行命令:
npm install @microsoft/signalr
  1. 创建SignalR服务
    新建src/app/signalr.service.ts:
import { Injectable } from '@angular/core';
import { HubConnection, HubConnectionBuilder } from '@microsoft/signalr';

@Injectable({
  providedIn: 'root'
})
export class SignalrService {
  private hubConnection!: HubConnection;

  startConnection(): void {
    this.hubConnection = new HubConnectionBuilder()
      .withUrl('https://localhost:5001/chatHub', {
        skipNegotiation: true, // 跳过传输协商,直接使用WebSocket
        transport: 0 // 0对应WebSocket传输,等价于HttpTransportType.WebSockets
      })
      .build();

    this.hubConnection.start()
      .then(() => console.log('WebSocket连接成功'))
      .catch(err => console.error('连接失败:', err));
  }

  // 注册消息接收监听
  onReceiveMessage(callback: (user: string, message: string) => void): void {
    this.hubConnection.on('ReceiveMessage', callback);
  }

  // 发送消息到服务端
  sendMessage(user: string, message: string): void {
    this.hubConnection.invoke('SendMessage', user, message)
      .catch(err => console.error('发送消息失败:', err));
  }
}

注意:withUrl中的地址需与后端MapHub的地址完全匹配,包括协议(http/https)和端口。

  1. 在组件中使用SignalR服务
    修改src/app/app.component.ts:
import { Component, OnInit } from '@angular/core';
import { SignalrService } from './signalr.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  user = '测试用户';
  message = '';
  messages: {user: string, text: string}[] = [];

  constructor(private signalrService: SignalrService) {}

  ngOnInit(): void {
    this.signalrService.startConnection();
    this.signalrService.onReceiveMessage((user, message) => {
      this.messages.push({user, text: message});
    });
  }

  sendMessage(): void {
    if (this.message.trim()) {
      this.signalrService.sendMessage(this.user, this.message);
      this.message = '';
    }
  }
}
  1. 更新组件模板
    修改src/app/app.component.html:
<div class="message-input">
  <input [(ngModel)]="user" placeholder="输入用户名" />
  <input [(ngModel)]="message" placeholder="输入消息" />
  <button (click)="sendMessage()">发送</button>
</div>
<div class="message-list">
  <div *ngFor="let msg of messages">
    <strong>{{msg.user}}:</strong> {{msg.text}}
  </div>
</div>

记得在AppModule中导入FormsModule,以支持ngModel指令。

常见问题排查

  • CORS错误:确保CORS策略中AllowCredentials已开启,且源地址与Angular运行地址一致,不能使用*作为源(会与AllowCredentials冲突)。
  • 混合内容问题:如果后端使用HTTPS,前端也必须使用HTTPS,开发环境可执行dotnet dev-certs https --trust信任开发证书。
  • 传输回退:默认SignalR会协商传输方式,若WebSocket不可用会回退到ServerSentEvents,通过skipNegotiation: true和指定WebSocket传输可强制使用WebSocket。

内容的提问来源于stack exchange,提问作者Marc Johnston

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 02:06:35