如何使用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
相关产品推荐
相关产品推荐

