128 lines
3.4 KiB
TypeScript
128 lines
3.4 KiB
TypeScript
|
|
import { useEventbus } from '@vben/hooks';
|
|||
|
|
import { useUserStore } from '@vben/stores';
|
|||
|
|
|
|||
|
|
import * as signalR from '@microsoft/signalr';
|
|||
|
|
import { notification } from 'ant-design-vue';
|
|||
|
|
|
|||
|
|
const eventbus = useEventbus();
|
|||
|
|
let connection: signalR.HubConnection;
|
|||
|
|
export function useSignalR() {
|
|||
|
|
/**
|
|||
|
|
* 开始连接SignalR
|
|||
|
|
*/
|
|||
|
|
async function startConnect() {
|
|||
|
|
try {
|
|||
|
|
const userStore = useUserStore();
|
|||
|
|
if (userStore.checkUserLoginExpire()) {
|
|||
|
|
console.debug('未检测到用户信息,登录之后才会链接SignalR.');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
connectionsignalR();
|
|||
|
|
await connection.start();
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error(error);
|
|||
|
|
setTimeout(() => startConnect(), 5000);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 关闭SignalR连接
|
|||
|
|
*/
|
|||
|
|
function closeConnect(): void {
|
|||
|
|
connection?.stop();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function connectionsignalR() {
|
|||
|
|
const userStore = useUserStore();
|
|||
|
|
const token = userStore.userInfo?.token;
|
|||
|
|
connection = new signalR.HubConnectionBuilder()
|
|||
|
|
.withUrl(import.meta.env.VITE_WEBSOCKET_URL, {
|
|||
|
|
accessTokenFactory: () => token,
|
|||
|
|
skipNegotiation: true,
|
|||
|
|
transport: signalR.HttpTransportType.WebSockets,
|
|||
|
|
})
|
|||
|
|
.withAutomaticReconnect({
|
|||
|
|
nextRetryDelayInMilliseconds: (retryContext) => {
|
|||
|
|
// 重连规则:重连次数<300:间隔1s;重试次数<3000:间隔3s;重试次数>3000:间隔30s
|
|||
|
|
const count = retryContext.previousRetryCount / 300;
|
|||
|
|
if (count < 1) {
|
|||
|
|
// 重试次数<300,间隔1s
|
|||
|
|
return 1000;
|
|||
|
|
} else if (count < 10) {
|
|||
|
|
// 重试次数>300:间隔5s
|
|||
|
|
return 1000 * 5;
|
|||
|
|
} // 重试次数>3000:间隔30s
|
|||
|
|
else {
|
|||
|
|
return 1000 * 30;
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
})
|
|||
|
|
.configureLogging(signalR.LogLevel.Debug)
|
|||
|
|
.build();
|
|||
|
|
|
|||
|
|
// 接收普通文本消息
|
|||
|
|
connection.on('ReceiveTextMessageAsync', ReceiveTextMessageHandlerAsync);
|
|||
|
|
// 接收广播消息
|
|||
|
|
connection.on(
|
|||
|
|
'ReceiveBroadCastMessageAsync',
|
|||
|
|
ReceiveBroadCastMessageHandlerAsync,
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 接收文本消息
|
|||
|
|
* @param message 消息体
|
|||
|
|
*/
|
|||
|
|
function ReceiveTextMessageHandlerAsync(message: any) {
|
|||
|
|
// 发布事件
|
|||
|
|
eventbus.publish('ReceiveTextMessageHandlerAsync', message);
|
|||
|
|
if (message.messageLevel === 10) {
|
|||
|
|
notification.warn({
|
|||
|
|
description: message.content,
|
|||
|
|
message: message.title,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
if (message.messageLevel === 20) {
|
|||
|
|
notification.info({
|
|||
|
|
message: message.title,
|
|||
|
|
description: message.content,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
if (message.messageLevel === 30) {
|
|||
|
|
notification.error({
|
|||
|
|
message: message.title,
|
|||
|
|
description: message.content,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 接收广播消息
|
|||
|
|
* @param message 消息体
|
|||
|
|
*/
|
|||
|
|
function ReceiveBroadCastMessageHandlerAsync(message: any) {
|
|||
|
|
// 发布事件
|
|||
|
|
eventbus.publish('ReceiveTextMessageHandlerAsync', message);
|
|||
|
|
if (message.messageLevel === 10) {
|
|||
|
|
notification.warn({
|
|||
|
|
message: message.title,
|
|||
|
|
description: message.content,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
if (message.messageLevel === 20) {
|
|||
|
|
notification.info({
|
|||
|
|
message: message.title,
|
|||
|
|
description: message.content,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
if (message.messageLevel === 30) {
|
|||
|
|
notification.error({
|
|||
|
|
message: message.title,
|
|||
|
|
description: message.content,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return { startConnect, closeConnect };
|
|||
|
|
}
|