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

如何使用ASP.NET Core+Angular搭配SignalR开发运行聊天应用

基于ASP.NET Core + SignalR + Angular的实时聊天应用开发指南

1. ASP.NET Core 后端配置与代码编写

  • 首先安装SignalR依赖包:打开VS Code终端进入ASP.NET Core项目根目录,运行命令
    dotnet add package Microsoft.AspNetCore.SignalR
  • 创建SignalR集线器类:在项目内新建Hubs文件夹,新增ChatHub.cs文件,代码如下:
    using Microsoft.AspNetCore.SignalR;
    // 替换为你自己的项目命名空间
    namespace YourProjectName.Hubs;
    
    public class ChatHub : Hub
    {
        // 接收前端发送的消息,广播给所有已连接的客户端
        public async Task SendMessage(string userName, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", userName, message);
        }
    }
    
  • 配置项目启动文件Program.cs,按顺序添加跨域、SignalR服务和路由配置:
    // ------------ 放在builder.Build()之前的配置区 ------------
    // 添加跨域规则,允许Angular前端访问,SignalR需要开启凭据支持
    builder.Services.AddCors(options =>
    {
        options.AddPolicy("AllowAngular", policy =>
        {
            policy.WithOrigins("http://localhost:4200") // 和你Angular实际运行地址保持一致
                  .AllowAnyHeader()
                  .AllowAnyMethod()
                  .AllowCredentials();
        });
    });
    // 注册SignalR服务
    builder.Services.AddSignalR();
    
    // ------------ 放在builder.Build()之后的中间件配置区,注意顺序 ------------
    // 跨域中间件要放在路由、授权中间件之间
    app.UseCors("AllowAngular");
    // 配置SignalR路由,前端通过这个地址连接后端
    app.MapHub<ChatHub>("/chathub");
    
  • 修改后端运行端口:打开Properties/launchSettings.json,把HTTP运行端口改为5000避免端口冲突,后续前端连接需要用到这个地址。

2. Angular 前端配置与代码编写

  • 安装SignalR客户端依赖:终端进入Angular项目根目录,运行命令
    npm install @microsoft/signalr
  • 新建聊天服务封装SignalR逻辑:运行命令ng generate service services/chat,编写chat.service.ts代码:
    import { Injectable } from '@angular/core';
    import * as signalR from '@microsoft/signalr';
    import { Subject } from 'rxjs';
    
    @Injectable({
      providedIn: 'root'
    })
    export class ChatService {
      private hubConnection: signalR.HubConnection;
      // 消息订阅源,组件订阅它接收实时消息
      public messageReceived = new Subject<{userName: string, message: string}>();
    
      constructor() {
        // 初始化连接,地址为后端运行地址+/chathub,和后端配置的路由一致
        this.hubConnection = new signalR.HubConnectionBuilder()
          .withUrl('http://localhost:5000/chathub')
          .build();
      }
    
      // 启动和后端的SignalR连接
      public startConnection = () => {
        this.hubConnection.start()
          .then(() => console.log('SignalR连接成功'))
          .catch(err => console.error('连接失败: ', err));
      }
    
      // 监听后端广播的消息
      public addReceiveMessageListener = () => {
        this.hubConnection.on('ReceiveMessage', (userName: string, message: string) => {
          this.messageReceived.next({userName, message});
        });
      }
    
      // 发送消息到后端
      public sendMessage = (userName: string, message: string) => {
        this.hubConnection.invoke('SendMessage', userName, message)
          .catch(err => console.error('发送消息失败: ', err));
      }
    }
    
  • 修改根组件逻辑,编写app.component.ts代码:
    import { Component, OnInit } from '@angular/core';
    import { ChatService } from './services/chat.service';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit {
      userName: string = '';
      message: string = '';
      messageList: {userName: string, message: string}[] = [];
    
      constructor(private chatService: ChatService) {}
    
      ngOnInit(): void {
        // 页面初始化时启动连接、监听消息
        this.chatService.startConnection();
        this.chatService.addReceiveMessageListener();
        // 订阅收到的消息,添加到消息列表
        this.chatService.messageReceived.subscribe(msg => {
          this.messageList.push(msg);
        });
      }
    
      // 发送消息按钮触发事件
      sendMsg() {
        if(this.userName.trim() && this.message.trim()) {
          this.chatService.sendMessage(this.userName, this.message);
          this.message = '';
        }
      }
    }
    
  • 编写聊天页面app.component.html代码:
    <div style="max-width: 600px; margin: 20px auto;">
      <h2>实时聊天室</h2>
      <div style="margin-bottom: 10px;">
        <input type="text" placeholder="请输入你的昵称" [(ngModel)]="userName" />
      </div>
      <div style="margin-bottom: 10px; display: flex; gap: 10px;">
        <input type="text" placeholder="请输入聊天内容" [(ngModel)]="message" style="flex: 1;" />
        <button (click)="sendMsg()">发送</button>
      </div>
      <div style="border: 1px solid #eee; padding: 10px; height: 400px; overflow-y: auto;">
        <div *ngFor="let msg of messageList" style="margin-bottom: 8px;">
          <strong>{{msg.userName}}:</strong>{{msg.message}}
        </div>
      </div>
    </div>
    
  • 配置app.module.ts导入必要模块:
    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms'; // 双向绑定需要
    import { HttpClientModule } from '@angular/common/http';
    
    import { AppComponent } from './app.component';
    
    @NgModule({
      declarations: [AppComponent],
      imports: [BrowserModule, FormsModule, HttpClientModule],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    

3. 运行流程

  • 启动后端:打开终端进入ASP.NET Core项目根目录,运行dotnet run,确认后端正常运行在http://localhost:5000
  • 启动前端:另开一个终端进入Angular项目根目录,运行ng serve --open,会自动打开浏览器访问http://localhost:4200
  • 功能测试:打开两个浏览器窗口,输入不同昵称发送消息,两个窗口都能实时收到消息即代表开发完成

常见问题排查

  • 跨域报错:检查后端跨域配置的前端地址是否和实际运行地址完全一致,跨域中间件的顺序是否正确
  • 连接失败:检查后端SignalR路由是否正确,后端服务是否正常启动
  • 收不到消息:检查后端SendMessage方法的事件名和前端监听的事件名是否完全一致,SignalR的事件名大小写敏感

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 20:15:03