@aspnet/signalr
是 ASP.NET Core SignalR 的客户端库,用于在前端应用中与 SignalR 服务器进行实时通信。SignalR 是一个强大的库,支持 WebSocket、Server-Sent Events (SSE) 和长轮询等传输方式,能够实现服务器与客户端之间的双向通信。
一、主要特点和用途:
1. 实时双向通信
- 服务器可以实时推送数据到客户端
- 客户端可以实时发送数据到服务器
- 支持多种传输协议(WebSocket、Server-Sent Events、Long Polling)
2. 常见应用场景
- 实时聊天应用
- 实时数据更新(如股票价格、游戏状态)
- 实时通知系统
- 协作工具(如在线文档编辑)
二、在前端使用的基本步骤:
1. 安装 @aspnet/signalr
包
首先,你需要通过 npm 或 yarn 安装 @aspnet/signalr
包。
bash
npm install @aspnet/signalr
或者
sql
yarn add @aspnet/signalr
2. 创建 SignalR 连接
在你的前端代码中,你可以创建一个 SignalR 连接并启动它。
javascript
import * as signalR from "@aspnet/signalr";
// 创建连接
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chatHub") // 指定 SignalR Hub 的 URL
.configureLogging(signalR.LogLevel.Information) // 配置日志级别
.build();
// 启动连接
connection.start()
.then(() => {
console.log("SignalR 连接已建立");
})
.catch(err => {
console.error("SignalR 连接失败: ", err);
});
// 监听服务器端发送的消息
connection.on("ReceiveMessage", (user, message) => {
console.log(`${user}: ${message}`);
});
// 发送消息到服务器端
function sendMessage(user, message) {
connection.invoke("SendMessage", user, message)
.catch(err => {
console.error("发送消息失败: ", err);
});
}
三、在angular中的实现
1、封装一个类
js
import { Injectable } from '@angular/core';
import Base64 from 'crypto-js/enc-base64';
import sha256 from 'crypto-js/sha256';
import * as signalR from '@aspnet/signalr';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SignalrService {
// tslint:disable-next-line:no-any
public message$: BehaviorSubject<any> = new BehaviorSubject<any>(null);
public connection: signalR.HubConnection;
constructor() { }
public async connectSignal(url: string): Promise<void> {
// 设置超时时间(30分钟超时)
this.connection = new signalR.HubConnectionBuilder().withUrl(url, {
accessTokenFactory: () => {
const time = Date.now();
const sign = Base64.stringify(sha256(('admin') + ':' + time + ':constsalt')); // 加密信息,与后端通信密语
return ('admin') + '.' + time + '.' + sign;
}
})
.configureLogging(signalR.LogLevel.Information)
.build();
this.connection.keepAliveIntervalInMilliseconds = 30 * 60 * 1000;
this.connection.serverTimeoutInMilliseconds = 30 * 60 * 1000;
await this.start();
this.connection.on('Notification', (message) => {
this.message$.next(message); // 拿到消息,发出去给订阅者
});
this.connection.onclose(() => {
// 断线重连
setTimeout(() => {
this.connectSignal(url);
}, 5000);
});
}
private async start(): Promise<void> {
await this.connection.start()
.then(() => {
})
.catch((err) => {
window.console.log(err);
setTimeout(() => {
this.start();
}, 5000);
});
}
public async close(callback?: Function): Promise<void> {
await this.connection.stop()
.then((res) => {
this.connection.invoke('Notification')
.then(() => {
})
})
.catch((err) => {
});
}
}
2、监听等待接受消息
js
import { Component, Input, OnInit } from '@angular/core';
import { SignalrService } from '@core';
@Component({
selector: 'bi-process-monitoring',
templateUrl: './process-monitoring.component.html',
styleUrls: ['./process-monitoring.component.scss']
})
export class ProcessMonitoringComponent implements OnInit {
constructor(
private _signalrService: SignalrService,
) {
this._listeningMessage();
}
public ngOnDestroy(): void {
this._signalrService.message$.unsubscribe();
}
/**
* 监听接口返回数据
*/
private _listeningMessage(): void {
this._signalrService.message$
.pipe(
filter(message => !!message),
takeUntil(this._destroy$)
)
.subscribe(message => {
if (message) {
const response = JSON.parse(message);
// 拿到消息,做你想要处理的就好
}
});
}
}