@havue/solutions 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -0
- package/bc-connect/README.md +3 -0
- package/bc-connect/dist/bc-connect.mjs +342 -0
- package/bc-connect/dist/bc-connect.umd.js +346 -0
- package/bc-connect/dist/types/src/index.d.ts +1 -0
- package/bc-connect/dist/types/src/manager.d.ts +135 -0
- package/bc-connect/package.json +38 -0
- package/bc-connect/src/index.ts +1 -0
- package/bc-connect/src/manager.ts +388 -0
- package/bc-connect/vite.config.ts +4 -0
- package/dist/solutions.full.js +8504 -0
- package/dist/solutions.full.min.js +18 -0
- package/dist/solutions.full.min.js.map +1 -0
- package/dist/solutions.mjs +2 -0
- package/dist/solutions.umd.js +18 -0
- package/dist/types/bc-connect/src/index.d.ts +1 -0
- package/dist/types/bc-connect/src/manager.d.ts +135 -0
- package/dist/types/src/index.d.ts +2 -0
- package/dist/types/ws-video-manager/src/hooks/useVideoPlay.d.ts +73 -0
- package/dist/types/ws-video-manager/src/index.d.ts +5 -0
- package/dist/types/ws-video-manager/src/loader/index.d.ts +2 -0
- package/dist/types/ws-video-manager/src/loader/websocket-loader.d.ts +62 -0
- package/dist/types/ws-video-manager/src/manager/index.d.ts +144 -0
- package/dist/types/ws-video-manager/src/render/drawer.d.ts +44 -0
- package/dist/types/ws-video-manager/src/render/index.d.ts +105 -0
- package/package.json +44 -0
- package/src/index.ts +2 -0
- package/vite.config.ts +4 -0
- package/ws-video-manager/README.md +3 -0
- package/ws-video-manager/dist/types/src/hooks/useVideoPlay.d.ts +73 -0
- package/ws-video-manager/dist/types/src/index.d.ts +5 -0
- package/ws-video-manager/dist/types/src/loader/index.d.ts +2 -0
- package/ws-video-manager/dist/types/src/loader/websocket-loader.d.ts +62 -0
- package/ws-video-manager/dist/types/src/manager/index.d.ts +144 -0
- package/ws-video-manager/dist/types/src/render/drawer.d.ts +44 -0
- package/ws-video-manager/dist/types/src/render/index.d.ts +105 -0
- package/ws-video-manager/dist/ws-video-manager.mjs +8132 -0
- package/ws-video-manager/dist/ws-video-manager.umd.js +8135 -0
- package/ws-video-manager/node_modules/.bin/tsc +17 -0
- package/ws-video-manager/node_modules/.bin/tsc.CMD +12 -0
- package/ws-video-manager/node_modules/.bin/tsc.ps1 +41 -0
- package/ws-video-manager/node_modules/.bin/tsserver +17 -0
- package/ws-video-manager/node_modules/.bin/tsserver.CMD +12 -0
- package/ws-video-manager/node_modules/.bin/tsserver.ps1 +41 -0
- package/ws-video-manager/package.json +41 -0
- package/ws-video-manager/src/hooks/useVideoPlay.ts +357 -0
- package/ws-video-manager/src/index.ts +6 -0
- package/ws-video-manager/src/loader/index.ts +3 -0
- package/ws-video-manager/src/loader/websocket-loader.ts +278 -0
- package/ws-video-manager/src/manager/index.ts +429 -0
- package/ws-video-manager/src/render/drawer.ts +255 -0
- package/ws-video-manager/src/render/index.ts +475 -0
- package/ws-video-manager/vite.config.ts +4 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/** 事件数据类型 */
|
|
2
|
+
export type BcConnectSendMessageType = {
|
|
3
|
+
/** 事件类型 */
|
|
4
|
+
type: string;
|
|
5
|
+
/** 数据 */
|
|
6
|
+
data: any;
|
|
7
|
+
/** 发送事件的实例id */
|
|
8
|
+
id: number;
|
|
9
|
+
/** 消息是发送给目标实例id的 */
|
|
10
|
+
targetId?: number;
|
|
11
|
+
};
|
|
12
|
+
/** 事件类型 */
|
|
13
|
+
export declare enum BcConnectEventTypeEnum {
|
|
14
|
+
/** 初始广播 */
|
|
15
|
+
Broadcast = "Hello world",
|
|
16
|
+
/** 回复初始广播 */
|
|
17
|
+
Broadcast_Reply = "I can hear you",
|
|
18
|
+
/** 主节点心跳 */
|
|
19
|
+
Main_Node_Hearbeat = "\u82CD\u5929\u8FD8\u5728\uFF0C\u522B\u7ACB\u9EC4\u5929",
|
|
20
|
+
/** 回复主节点心跳 */
|
|
21
|
+
Res_Main_Node_Hearbeat = "\u82CD\u5929\u5728\u4E0A\uFF0C\u53D7\u6211\u4E00\u62DC",
|
|
22
|
+
/** 长时间未收到主节点心跳,我想当主节点,你们同意吗 */
|
|
23
|
+
Req_Be_Main_Node = "\u82CD\u5929\u5DF2\u6B7B\uFF0C\u9EC4\u5929\u5F53\u7ACB",
|
|
24
|
+
/** 排资论辈,我应是主节点,不同意 */
|
|
25
|
+
Res_Be_Main_Node = "\u6211\u662F\u9EC4\u5929\uFF0C\u5C14\u7B49\u9000\u4E0B",
|
|
26
|
+
/** 当前BC节点类型更改 */
|
|
27
|
+
Node_Type_Change = "node type change",
|
|
28
|
+
/** 其他标签页BC节点id列表更新 */
|
|
29
|
+
Friend_List_Update = "friend list update"
|
|
30
|
+
}
|
|
31
|
+
/** 当前webview BroadcastChannel节点类型 */
|
|
32
|
+
export declare enum BcConnectNodeTypeEnum {
|
|
33
|
+
Main = "main",
|
|
34
|
+
Normal = "normal"
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 使用BroadcastChannel与其他标签页进行通信
|
|
38
|
+
*/
|
|
39
|
+
export declare class BroadcastChannelManager {
|
|
40
|
+
/** 通道名称 */
|
|
41
|
+
private _bcName;
|
|
42
|
+
/** BroadcastChannel实例 */
|
|
43
|
+
private _broadcastChannel;
|
|
44
|
+
/** 事件map */
|
|
45
|
+
private _eventMap;
|
|
46
|
+
/** 主节点发送心跳的interval */
|
|
47
|
+
private _mainNodeMsgInterval;
|
|
48
|
+
/** 认为主节点掉线的timeout */
|
|
49
|
+
private _mainNoceMsgTimeoutTimer;
|
|
50
|
+
/** 当前实例id */
|
|
51
|
+
id: number;
|
|
52
|
+
/** 记录的友方id数组 */
|
|
53
|
+
private _oldFrendChannelIdList;
|
|
54
|
+
/** 正在更新的右方id数组 */
|
|
55
|
+
private _friendChannelIdSet;
|
|
56
|
+
/** 当前节点类型 */
|
|
57
|
+
private _nodeType;
|
|
58
|
+
/** 是否开启调试模式,会在控制台打印相关信息 */
|
|
59
|
+
private _debug;
|
|
60
|
+
constructor(name: string, debug?: boolean);
|
|
61
|
+
get nodeType(): BcConnectNodeTypeEnum | undefined;
|
|
62
|
+
get friendList(): number[];
|
|
63
|
+
connect(): void;
|
|
64
|
+
close(): void;
|
|
65
|
+
/**
|
|
66
|
+
* 切换节点类型
|
|
67
|
+
* @param {BcConnectNodeTypeEnum} type
|
|
68
|
+
* @returns
|
|
69
|
+
*/
|
|
70
|
+
private _setNodeType;
|
|
71
|
+
/** 更新友方列表 */
|
|
72
|
+
private _updateFriendList;
|
|
73
|
+
/** 绑定事件 */
|
|
74
|
+
private _bindBroadcastChannelEvent;
|
|
75
|
+
/** 监听节点类型切换事件 */
|
|
76
|
+
private _bindNodeEvent;
|
|
77
|
+
/** 获取最新的友方列表 */
|
|
78
|
+
private _getNewFriendList;
|
|
79
|
+
/**
|
|
80
|
+
* 更新当前节点类型
|
|
81
|
+
*/
|
|
82
|
+
private _updataNodeType;
|
|
83
|
+
private _timeoutToBeMainNode;
|
|
84
|
+
/**
|
|
85
|
+
* 保持记录的活跃的友方id列表
|
|
86
|
+
* 清空正在记录的友方id列表
|
|
87
|
+
*/
|
|
88
|
+
private _catchOldFriend;
|
|
89
|
+
/**
|
|
90
|
+
* 申请成为主节点
|
|
91
|
+
*/
|
|
92
|
+
private _req_beMainNode;
|
|
93
|
+
/**
|
|
94
|
+
* 添加友方
|
|
95
|
+
* @param id 节点id
|
|
96
|
+
*/
|
|
97
|
+
_addFriend(id: number): void;
|
|
98
|
+
/**
|
|
99
|
+
* 广播消息
|
|
100
|
+
* @param type 消息类型
|
|
101
|
+
* @param data 数据
|
|
102
|
+
*/
|
|
103
|
+
send(type: string, data?: any): void;
|
|
104
|
+
/**
|
|
105
|
+
* 给特定id的节点发送消息
|
|
106
|
+
* @param type 消息类型
|
|
107
|
+
* @param targetId 目标节点id
|
|
108
|
+
* @param data 数据
|
|
109
|
+
*/
|
|
110
|
+
sendToTarget(type: string, targetId: number, data?: any): void;
|
|
111
|
+
/**
|
|
112
|
+
* 注册事件
|
|
113
|
+
* @param { string } event 事件类型
|
|
114
|
+
* @param callback 回调
|
|
115
|
+
* @returns void
|
|
116
|
+
*/
|
|
117
|
+
on(event: string, callback: (_: BcConnectSendMessageType) => void): void;
|
|
118
|
+
/**
|
|
119
|
+
* 注销事件
|
|
120
|
+
* @param { string } event 事件类型
|
|
121
|
+
* @param callback 事件回调
|
|
122
|
+
* @returns
|
|
123
|
+
*/
|
|
124
|
+
off(event: string, callback?: (_: BcConnectSendMessageType) => void): void;
|
|
125
|
+
/**
|
|
126
|
+
* 触发事件
|
|
127
|
+
* @param { string } event 事件类型
|
|
128
|
+
* @param data 数据
|
|
129
|
+
*/
|
|
130
|
+
emit(event: string, data: BcConnectSendMessageType): void;
|
|
131
|
+
/**
|
|
132
|
+
* 销毁
|
|
133
|
+
*/
|
|
134
|
+
destroy(): void;
|
|
135
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@havue/bc-connect",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Javascript class for Broadcast channel connect",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"havue",
|
|
7
|
+
"broadcast",
|
|
8
|
+
"channel",
|
|
9
|
+
"solutions"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "vite build --mode package"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://happypedestrian.github.io/havue/guide/",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/HappyPedestrian/havue.git"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public",
|
|
23
|
+
"registry": "https://registry.npmjs.org/"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"main": "./dist/bc-connect.umd.js",
|
|
29
|
+
"module": "./dist/bc-connect.mjs",
|
|
30
|
+
"types": "./dist/types/src/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"require": "./dist/bc-connect.umd.js",
|
|
34
|
+
"import": "./dist/bc-connect.mjs",
|
|
35
|
+
"types": "./dist/types/src/index.d.ts"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './manager'
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
// #region typedefine
|
|
2
|
+
/** 事件数据类型 */
|
|
3
|
+
export type BcConnectSendMessageType = {
|
|
4
|
+
/** 事件类型 */
|
|
5
|
+
type: string
|
|
6
|
+
/** 数据 */
|
|
7
|
+
data: any
|
|
8
|
+
/** 发送事件的实例id */
|
|
9
|
+
id: number
|
|
10
|
+
/** 消息是发送给目标实例id的 */
|
|
11
|
+
targetId?: number
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** 事件类型 */
|
|
15
|
+
export enum BcConnectEventTypeEnum {
|
|
16
|
+
/** 初始广播 */
|
|
17
|
+
Broadcast = 'Hello world',
|
|
18
|
+
/** 回复初始广播 */
|
|
19
|
+
Broadcast_Reply = 'I can hear you',
|
|
20
|
+
/** 主节点心跳 */
|
|
21
|
+
Main_Node_Hearbeat = '苍天还在,别立黄天',
|
|
22
|
+
/** 回复主节点心跳 */
|
|
23
|
+
Res_Main_Node_Hearbeat = '苍天在上,受我一拜',
|
|
24
|
+
/** 长时间未收到主节点心跳,我想当主节点,你们同意吗 */
|
|
25
|
+
Req_Be_Main_Node = '苍天已死,黄天当立',
|
|
26
|
+
/** 排资论辈,我应是主节点,不同意 */
|
|
27
|
+
Res_Be_Main_Node = '我是黄天,尔等退下',
|
|
28
|
+
/** 当前BC节点类型更改 */
|
|
29
|
+
Node_Type_Change = 'node type change',
|
|
30
|
+
/** 其他标签页BC节点id列表更新 */
|
|
31
|
+
Friend_List_Update = 'friend list update'
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** 当前webview BroadcastChannel节点类型 */
|
|
35
|
+
export enum BcConnectNodeTypeEnum {
|
|
36
|
+
Main = 'main',
|
|
37
|
+
Normal = 'normal'
|
|
38
|
+
}
|
|
39
|
+
// #endregion typedefine
|
|
40
|
+
|
|
41
|
+
// 消息超时时间
|
|
42
|
+
const MessageTimeout = 300
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 使用BroadcastChannel与其他标签页进行通信
|
|
46
|
+
*/
|
|
47
|
+
export class BroadcastChannelManager {
|
|
48
|
+
/** 通道名称 */
|
|
49
|
+
private _bcName: string
|
|
50
|
+
/** BroadcastChannel实例 */
|
|
51
|
+
private _broadcastChannel: BroadcastChannel | undefined = undefined
|
|
52
|
+
/** 事件map */
|
|
53
|
+
private _eventMap: Map<string, Array<(_: BcConnectSendMessageType) => void>>
|
|
54
|
+
/** 主节点发送心跳的interval */
|
|
55
|
+
private _mainNodeMsgInterval: number | null = null
|
|
56
|
+
/** 认为主节点掉线的timeout */
|
|
57
|
+
private _mainNoceMsgTimeoutTimer: number | null = null
|
|
58
|
+
/** 当前实例id */
|
|
59
|
+
public id: number = Date.now() + Math.random()
|
|
60
|
+
/** 记录的友方id数组 */
|
|
61
|
+
private _oldFrendChannelIdList: Array<number> = []
|
|
62
|
+
/** 正在更新的右方id数组 */
|
|
63
|
+
private _friendChannelIdSet: Set<number> = new Set()
|
|
64
|
+
/** 当前节点类型 */
|
|
65
|
+
private _nodeType: BcConnectNodeTypeEnum | undefined = undefined
|
|
66
|
+
|
|
67
|
+
/** 是否开启调试模式,会在控制台打印相关信息 */
|
|
68
|
+
private _debug: boolean = false
|
|
69
|
+
|
|
70
|
+
constructor(name: string, debug: boolean = false) {
|
|
71
|
+
this._debug = debug
|
|
72
|
+
this._bcName = name
|
|
73
|
+
this._eventMap = new Map()
|
|
74
|
+
this._debug && console.log('BC:id:', this.id)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
get nodeType() {
|
|
78
|
+
return this._nodeType
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
get friendList() {
|
|
82
|
+
return [...this._oldFrendChannelIdList]
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public connect() {
|
|
86
|
+
this._debug && console.log('BC:bc connect')
|
|
87
|
+
this.close()
|
|
88
|
+
this._broadcastChannel = new BroadcastChannel(this._bcName)
|
|
89
|
+
this._bindBroadcastChannelEvent()
|
|
90
|
+
this._updateFriendList()
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public close() {
|
|
94
|
+
this._debug && console.log('BC:bc close')
|
|
95
|
+
this._broadcastChannel && this._broadcastChannel.close()
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* 切换节点类型
|
|
100
|
+
* @param {BcConnectNodeTypeEnum} type
|
|
101
|
+
* @returns
|
|
102
|
+
*/
|
|
103
|
+
private _setNodeType(type: BcConnectNodeTypeEnum) {
|
|
104
|
+
if (this._nodeType === type) {
|
|
105
|
+
return
|
|
106
|
+
}
|
|
107
|
+
this._nodeType = type
|
|
108
|
+
this.emit(BcConnectEventTypeEnum.Node_Type_Change, {
|
|
109
|
+
type: BcConnectEventTypeEnum.Node_Type_Change,
|
|
110
|
+
data: type,
|
|
111
|
+
id: this.id
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** 更新友方列表 */
|
|
116
|
+
private _updateFriendList() {
|
|
117
|
+
// 广播告知己方存在
|
|
118
|
+
this.send(BcConnectEventTypeEnum.Broadcast)
|
|
119
|
+
|
|
120
|
+
setTimeout(() => {
|
|
121
|
+
this._oldFrendChannelIdList = this._getNewFriendList()
|
|
122
|
+
this._debug && console.log('BC:connect:updateFriendChannelIdList:', this._oldFrendChannelIdList)
|
|
123
|
+
this.emit(BcConnectEventTypeEnum.Friend_List_Update, {
|
|
124
|
+
type: BcConnectEventTypeEnum.Friend_List_Update,
|
|
125
|
+
data: [...this._oldFrendChannelIdList],
|
|
126
|
+
id: this.id
|
|
127
|
+
})
|
|
128
|
+
this._updataNodeType()
|
|
129
|
+
}, MessageTimeout)
|
|
130
|
+
}
|
|
131
|
+
/** 绑定事件 */
|
|
132
|
+
private _bindBroadcastChannelEvent() {
|
|
133
|
+
this._broadcastChannel &&
|
|
134
|
+
(this._broadcastChannel.onmessage = (event) => {
|
|
135
|
+
const { type, targetId } = event.data
|
|
136
|
+
if (targetId && targetId !== this.id) {
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
this.emit(type, event.data)
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
// 收到世界呼唤
|
|
143
|
+
this.on(BcConnectEventTypeEnum.Broadcast, (data) => {
|
|
144
|
+
const { id } = data
|
|
145
|
+
if (!this._friendChannelIdSet.has(id)) {
|
|
146
|
+
this._friendChannelIdSet.add(id)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
this.sendToTarget(BcConnectEventTypeEnum.Broadcast_Reply, id)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
// 收到友方存在
|
|
153
|
+
this.on(BcConnectEventTypeEnum.Broadcast_Reply, (data) => {
|
|
154
|
+
const { id } = data
|
|
155
|
+
this._addFriend(id)
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
// 收到其他申请为主节点
|
|
159
|
+
this.on(BcConnectEventTypeEnum.Req_Be_Main_Node, (data) => {
|
|
160
|
+
const { id } = data
|
|
161
|
+
if (id > this.id) {
|
|
162
|
+
this.sendToTarget(BcConnectEventTypeEnum.Res_Be_Main_Node, id)
|
|
163
|
+
}
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
// 收到其他节点回复主节点心跳
|
|
167
|
+
this.on(BcConnectEventTypeEnum.Res_Main_Node_Hearbeat, (data) => {
|
|
168
|
+
this._addFriend(data.id)
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
this._bindNodeEvent()
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** 监听节点类型切换事件 */
|
|
175
|
+
private _bindNodeEvent() {
|
|
176
|
+
const onMainNodeHearbeat = (data: BcConnectSendMessageType) => {
|
|
177
|
+
this._timeoutToBeMainNode()
|
|
178
|
+
this._catchOldFriend()
|
|
179
|
+
this._addFriend(data.id)
|
|
180
|
+
this.send(BcConnectEventTypeEnum.Res_Main_Node_Hearbeat)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
this.on(BcConnectEventTypeEnum.Node_Type_Change, (info) => {
|
|
184
|
+
const { data } = info
|
|
185
|
+
this._mainNodeMsgInterval && clearInterval(this._mainNodeMsgInterval)
|
|
186
|
+
this._debug && console.log('BC:代理类型切换:', info.data)
|
|
187
|
+
if (data === BcConnectNodeTypeEnum.Main) {
|
|
188
|
+
// 定时发送主节点心跳
|
|
189
|
+
this._mainNodeMsgInterval = setInterval(() => {
|
|
190
|
+
this._catchOldFriend()
|
|
191
|
+
this.send(BcConnectEventTypeEnum.Main_Node_Hearbeat)
|
|
192
|
+
}, MessageTimeout)
|
|
193
|
+
} else if (data === BcConnectNodeTypeEnum.Normal) {
|
|
194
|
+
this._timeoutToBeMainNode()
|
|
195
|
+
}
|
|
196
|
+
// 收到主节点心跳, 重新更新友方列表
|
|
197
|
+
this.on(BcConnectEventTypeEnum.Main_Node_Hearbeat, onMainNodeHearbeat)
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** 获取最新的友方列表 */
|
|
202
|
+
private _getNewFriendList() {
|
|
203
|
+
return [...this._friendChannelIdSet].sort((a, b) => a - b)
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* 更新当前节点类型
|
|
207
|
+
*/
|
|
208
|
+
private _updataNodeType() {
|
|
209
|
+
this._mainNodeMsgInterval && clearInterval(this._mainNodeMsgInterval)
|
|
210
|
+
if (this._oldFrendChannelIdList.length === 0 || Math.min(...this._oldFrendChannelIdList) > this.id) {
|
|
211
|
+
if (this._nodeType === BcConnectNodeTypeEnum.Main) {
|
|
212
|
+
return
|
|
213
|
+
}
|
|
214
|
+
this._setNodeType(BcConnectNodeTypeEnum.Main)
|
|
215
|
+
} else {
|
|
216
|
+
if (this._nodeType === BcConnectNodeTypeEnum.Normal) {
|
|
217
|
+
return
|
|
218
|
+
}
|
|
219
|
+
this._setNodeType(BcConnectNodeTypeEnum.Normal)
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
private _timeoutToBeMainNode() {
|
|
224
|
+
this._mainNoceMsgTimeoutTimer && clearTimeout(this._mainNoceMsgTimeoutTimer)
|
|
225
|
+
// 超时未收到心跳,认为主节点掉线,申请为主节点
|
|
226
|
+
this._mainNoceMsgTimeoutTimer = setTimeout(() => {
|
|
227
|
+
this._req_beMainNode()
|
|
228
|
+
}, MessageTimeout * 3)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* 保持记录的活跃的友方id列表
|
|
233
|
+
* 清空正在记录的友方id列表
|
|
234
|
+
*/
|
|
235
|
+
private _catchOldFriend() {
|
|
236
|
+
const newFriendList = this._getNewFriendList()
|
|
237
|
+
if (this._oldFrendChannelIdList.join() !== newFriendList.join()) {
|
|
238
|
+
this._debug && console.log('BC:updateFriendChannelIdList:', newFriendList)
|
|
239
|
+
this.emit(BcConnectEventTypeEnum.Friend_List_Update, {
|
|
240
|
+
type: BcConnectEventTypeEnum.Friend_List_Update,
|
|
241
|
+
data: [...newFriendList],
|
|
242
|
+
id: this.id
|
|
243
|
+
})
|
|
244
|
+
this._oldFrendChannelIdList = [...newFriendList]
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (this._nodeType === BcConnectNodeTypeEnum.Main && Math.min(...this._oldFrendChannelIdList) < this.id) {
|
|
248
|
+
// 有更小的id,不再为主节点
|
|
249
|
+
this._setNodeType(BcConnectNodeTypeEnum.Normal)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
this._friendChannelIdSet.clear()
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* 申请成为主节点
|
|
257
|
+
*/
|
|
258
|
+
private _req_beMainNode() {
|
|
259
|
+
this._debug && console.log('BC:req_beMainNode')
|
|
260
|
+
|
|
261
|
+
// 向所有id友方节点发送申请
|
|
262
|
+
this.send(BcConnectEventTypeEnum.Req_Be_Main_Node)
|
|
263
|
+
|
|
264
|
+
// 如果长时间未回复,认为自己可以当主节点
|
|
265
|
+
const timer = setTimeout(() => {
|
|
266
|
+
this._setNodeType(BcConnectNodeTypeEnum.Main)
|
|
267
|
+
}, MessageTimeout)
|
|
268
|
+
|
|
269
|
+
// 收到拒绝回复,清空timeout
|
|
270
|
+
const handleRes_beMainNode = () => {
|
|
271
|
+
clearTimeout(timer)
|
|
272
|
+
this.off(BcConnectEventTypeEnum.Res_Be_Main_Node, handleRes_beMainNode)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
this.on(BcConnectEventTypeEnum.Res_Be_Main_Node, handleRes_beMainNode)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* 添加友方
|
|
280
|
+
* @param id 节点id
|
|
281
|
+
*/
|
|
282
|
+
public _addFriend(id: number) {
|
|
283
|
+
if (!this._friendChannelIdSet.has(id)) {
|
|
284
|
+
this._friendChannelIdSet.add(id)
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* 广播消息
|
|
290
|
+
* @param type 消息类型
|
|
291
|
+
* @param data 数据
|
|
292
|
+
*/
|
|
293
|
+
public send(type: string, data?: any) {
|
|
294
|
+
this._broadcastChannel?.postMessage({
|
|
295
|
+
type,
|
|
296
|
+
data,
|
|
297
|
+
id: this.id
|
|
298
|
+
})
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* 给特定id的节点发送消息
|
|
303
|
+
* @param type 消息类型
|
|
304
|
+
* @param targetId 目标节点id
|
|
305
|
+
* @param data 数据
|
|
306
|
+
*/
|
|
307
|
+
public sendToTarget(type: string, targetId: number, data?: any) {
|
|
308
|
+
this._broadcastChannel?.postMessage({
|
|
309
|
+
type,
|
|
310
|
+
data,
|
|
311
|
+
id: this.id,
|
|
312
|
+
targetId
|
|
313
|
+
})
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* 注册事件
|
|
318
|
+
* @param { string } event 事件类型
|
|
319
|
+
* @param callback 回调
|
|
320
|
+
* @returns void
|
|
321
|
+
*/
|
|
322
|
+
public on(event: string, callback: (_: BcConnectSendMessageType) => void) {
|
|
323
|
+
const callbacks = this._eventMap.get(event)
|
|
324
|
+
if (!callbacks) {
|
|
325
|
+
this._eventMap.set(event, [callback])
|
|
326
|
+
return
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (callbacks.includes(callback)) {
|
|
330
|
+
return
|
|
331
|
+
}
|
|
332
|
+
callbacks.push(callback)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* 注销事件
|
|
337
|
+
* @param { string } event 事件类型
|
|
338
|
+
* @param callback 事件回调
|
|
339
|
+
* @returns
|
|
340
|
+
*/
|
|
341
|
+
public off(event: string, callback?: (_: BcConnectSendMessageType) => void) {
|
|
342
|
+
const callbacks = this._eventMap.get(event)
|
|
343
|
+
if (!callbacks) {
|
|
344
|
+
return
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (!callback) {
|
|
348
|
+
callbacks.length = 0
|
|
349
|
+
return
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const index = callbacks.indexOf(callback)
|
|
353
|
+
callbacks.splice(index, 1)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* 触发事件
|
|
358
|
+
* @param { string } event 事件类型
|
|
359
|
+
* @param data 数据
|
|
360
|
+
*/
|
|
361
|
+
public emit(event: string, data: BcConnectSendMessageType) {
|
|
362
|
+
const callbacks = this._eventMap.get(event) || []
|
|
363
|
+
|
|
364
|
+
callbacks.forEach((cb) => {
|
|
365
|
+
cb(data)
|
|
366
|
+
})
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* 销毁
|
|
371
|
+
*/
|
|
372
|
+
public destroy() {
|
|
373
|
+
this._bcName = ''
|
|
374
|
+
this._eventMap.clear()
|
|
375
|
+
this._broadcastChannel?.close()
|
|
376
|
+
this._broadcastChannel = undefined
|
|
377
|
+
this._oldFrendChannelIdList = []
|
|
378
|
+
this._friendChannelIdSet.clear()
|
|
379
|
+
this.id = -1
|
|
380
|
+
this._nodeType = undefined
|
|
381
|
+
|
|
382
|
+
this._mainNodeMsgInterval && clearInterval(this._mainNodeMsgInterval)
|
|
383
|
+
this._mainNodeMsgInterval = null
|
|
384
|
+
this._mainNoceMsgTimeoutTimer && clearInterval(this._mainNoceMsgTimeoutTimer)
|
|
385
|
+
this._mainNoceMsgTimeoutTimer = null
|
|
386
|
+
this._debug && console.log('BC:destroy')
|
|
387
|
+
}
|
|
388
|
+
}
|