yjz-web-sdk 1.0.10 → 1.0.11-beta.1
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/lib/components/RemotePlayer/index.vue.d.ts +1 -73
- package/lib/composables/useCursorStyle.d.ts +1 -1
- package/lib/composables/useKeyboardControl.d.ts +1 -1
- package/lib/composables/useMouseTouchControl.d.ts +4 -4
- package/lib/composables/useRemoteVideo.d.ts +8 -25
- package/lib/composables/useResizeObserver.d.ts +1 -1
- package/lib/core/data/WebRtcError.d.ts +1 -2
- package/lib/core/data/WebrtcDataType.d.ts +1 -11
- package/lib/core/groupctrl/SdkController.d.ts +2 -2
- package/lib/core/rtc/WebRTCClient.d.ts +2 -5
- package/lib/core/rtc/WebRTCConfig.d.ts +1 -1
- package/lib/core/rtc/WebRtcNegotiate.d.ts +2 -2
- package/lib/core/signal/SignalingClient.d.ts +1 -1
- package/lib/core/util/TurnTestUtil.d.ts +2 -2
- package/lib/yjz-web-sdk.js +496 -1236
- package/package.json +5 -16
- package/lib/components/RemotePlayer/type.d.ts +0 -9
- package/lib/core/util/MapCache.d.ts +0 -20
- package/lib/render/Canvas2DRenderer.d.ts +0 -10
- package/lib/render/WebGLRenderer.d.ts +0 -16
- package/lib/render/WebGPURenderer.d.ts +0 -18
- package/lib/types/index.d.ts +0 -13
- package/lib/util/WasmUtil.d.ts +0 -17
- package/lib/worker/worker.d.ts +0 -1
- package/src/assets/icon/circle.svg +0 -1
- package/src/assets/icon/triangle.svg +0 -1
- package/src/assets/wasm/h264-atomic.wasm +0 -0
- package/src/assets/wasm/h264-simd.wasm +0 -0
- package/src/components/RemotePlayer/index.vue +0 -170
- package/src/components/RemotePlayer/type.ts +0 -11
- package/src/composables/useCursorStyle.ts +0 -15
- package/src/composables/useKeyboardControl.ts +0 -32
- package/src/composables/useMouseTouchControl.ts +0 -158
- package/src/composables/useRemoteVideo.ts +0 -248
- package/src/composables/useResizeObserver.ts +0 -27
- package/src/core/WebRTCSdk.ts +0 -561
- package/src/core/data/MessageType.ts +0 -70
- package/src/core/data/TurnType.ts +0 -25
- package/src/core/data/WebRtcError.ts +0 -93
- package/src/core/data/WebrtcDataType.ts +0 -354
- package/src/core/groupctrl/GroupCtrlSocketManager.ts +0 -94
- package/src/core/groupctrl/SdkController.ts +0 -96
- package/src/core/rtc/WebRTCClient.ts +0 -862
- package/src/core/rtc/WebRTCConfig.ts +0 -86
- package/src/core/rtc/WebRtcNegotiate.ts +0 -164
- package/src/core/signal/SignalingClient.ts +0 -221
- package/src/core/util/FileTypeUtils.ts +0 -75
- package/src/core/util/KeyCodeUtil.ts +0 -162
- package/src/core/util/Logger.ts +0 -83
- package/src/core/util/MapCache.ts +0 -135
- package/src/core/util/ScreenControlUtil.ts +0 -174
- package/src/core/util/TurnTestUtil.ts +0 -123
- package/src/env.d.ts +0 -30
- package/src/index.ts +0 -61
- package/src/render/Canvas2DRenderer.ts +0 -38
- package/src/render/WebGLRenderer.ts +0 -150
- package/src/render/WebGPURenderer.ts +0 -194
- package/src/types/index.ts +0 -15
- package/src/types/webgpu.d.ts +0 -1158
- package/src/util/WasmUtil.ts +0 -291
- package/src/worker/worker.ts +0 -292
package/src/core/WebRTCSdk.ts
DELETED
|
@@ -1,561 +0,0 @@
|
|
|
1
|
-
import {EventEmitter} from 'eventemitter3'
|
|
2
|
-
import {SignalingClient} from './signal/SignalingClient'
|
|
3
|
-
import {WebRTCClient} from './rtc/WebRTCClient'
|
|
4
|
-
import type {WebRTCConfigOptions} from './rtc/WebRTCConfig'
|
|
5
|
-
import {WebRTCConfig} from './rtc/WebRTCConfig'
|
|
6
|
-
import {ConnectorType, MessageType, SendType} from './data/MessageType'
|
|
7
|
-
import {
|
|
8
|
-
ChannelData,
|
|
9
|
-
ChannelDataType,
|
|
10
|
-
type CloudStatusPayload,
|
|
11
|
-
KeyEventData,
|
|
12
|
-
type ScreenStats,
|
|
13
|
-
} from './data/WebrtcDataType'
|
|
14
|
-
import {
|
|
15
|
-
type CameraError,
|
|
16
|
-
CameraFailCode,
|
|
17
|
-
createCameraError,
|
|
18
|
-
createWebRtcError,
|
|
19
|
-
EmitType,
|
|
20
|
-
FailCode,
|
|
21
|
-
type WebRtcError,
|
|
22
|
-
} from './data/WebRtcError'
|
|
23
|
-
import {areTurnListsEmpty, selectBestTurnServer} from './util/TurnTestUtil'
|
|
24
|
-
// import {MapCache} from "./util/MapCache.ts";
|
|
25
|
-
import {enableLog, Logger, setLogLevel} from "./util/Logger";
|
|
26
|
-
import {formattedTime} from "./util/FileTypeUtils";
|
|
27
|
-
|
|
28
|
-
export class WebRTCSdk extends EventEmitter {
|
|
29
|
-
public config: WebRTCConfig | null = null
|
|
30
|
-
public signalingClient: SignalingClient | null = null
|
|
31
|
-
public webRTCClient: WebRTCClient | null = null
|
|
32
|
-
public options: WebRTCConfigOptions
|
|
33
|
-
public isConnected: boolean = false
|
|
34
|
-
public isConnecting: boolean = false
|
|
35
|
-
private connectCount: number = 0
|
|
36
|
-
private MAX_COUNT: number = 1
|
|
37
|
-
private timeout: ReturnType<typeof setTimeout> | null = null
|
|
38
|
-
|
|
39
|
-
constructor(options: WebRTCConfigOptions) {
|
|
40
|
-
super()
|
|
41
|
-
// 初始化配置
|
|
42
|
-
this.options = options
|
|
43
|
-
if(this.options.connectorType !== ConnectorType.LanForwarding) {
|
|
44
|
-
enableLog(!!this.options.enableLogger);
|
|
45
|
-
if(this.options.enableLogger !== undefined && this.options.enableLogger){
|
|
46
|
-
if(this.options.loggerLevel !== undefined) {
|
|
47
|
-
setLogLevel(this.options.loggerLevel);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if(this.options.maxRecount){
|
|
53
|
-
this.MAX_COUNT = this.options.maxRecount;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async initConfig(): Promise<void> {
|
|
58
|
-
if (!this.options || Object.keys(this.options).length === 0) {
|
|
59
|
-
throw createWebRtcError(FailCode.OPTION_ERR, 'option null');
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (areTurnListsEmpty(this.options)) {
|
|
63
|
-
throw createWebRtcError(FailCode.OPTION_ERR, '中继配置为空');
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const tryTurnList = async (list: string[], isHost: boolean): Promise<boolean> => {
|
|
67
|
-
if (list.length === 0) return false;
|
|
68
|
-
try {
|
|
69
|
-
const result = await selectBestTurnServer(list)
|
|
70
|
-
if (result.url && typeof result.rtt === 'number') {
|
|
71
|
-
if(isHost && result.rtt > 150) {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
this.options.turnServerUri = result.url;
|
|
75
|
-
this.options.turnKey = [result.url];
|
|
76
|
-
return true;
|
|
77
|
-
} else {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
} catch (e) {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const triedHost = this.options.hostTurn?.length
|
|
86
|
-
? await tryTurnList(this.options.hostTurn, true)
|
|
87
|
-
: false;
|
|
88
|
-
if (!triedHost && this.options.spareTurn?.length) {
|
|
89
|
-
const allTurns = (this.options.hostTurn ?? []).concat(this.options.spareTurn ?? []);
|
|
90
|
-
const triedSpare = await tryTurnList(allTurns, false);
|
|
91
|
-
if (!triedSpare) {
|
|
92
|
-
if (this.options.turnServerUri) {
|
|
93
|
-
this.options.turnKey = [this.options.turnServerUri];
|
|
94
|
-
}else {
|
|
95
|
-
throw createWebRtcError(FailCode.OPTION_ERR, '暂无可用TURN服务器');
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
} else if (!triedHost) {
|
|
99
|
-
const triedSpare = await tryTurnList(this.options.hostTurn?? [], false);
|
|
100
|
-
if (!triedSpare) {
|
|
101
|
-
if (this.options.turnServerUri) {
|
|
102
|
-
this.options.turnKey = [this.options.turnServerUri];
|
|
103
|
-
}else {
|
|
104
|
-
throw createWebRtcError(FailCode.OPTION_ERR, '暂无可用TURN服务器');
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/** 开始连接 signal 服务 */
|
|
111
|
-
public startConnection(): void {
|
|
112
|
-
this.prepareConnection().catch((err) => {
|
|
113
|
-
Logger.error('错误信息:', `sdk调试错误日志======>`, err)
|
|
114
|
-
this.emit(EmitType.webrtcError, err)
|
|
115
|
-
})
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
private async prepareConnection(): Promise<void> {
|
|
119
|
-
if (this.isConnecting) return
|
|
120
|
-
this.isConnecting = true
|
|
121
|
-
try {
|
|
122
|
-
if (areTurnListsEmpty(this.options)) {
|
|
123
|
-
if (!this.options.turnServerUri) {
|
|
124
|
-
Logger.error('错误信息:', `sdk调试错误日志======> 暂无可用TURN服务器`)
|
|
125
|
-
this.emit(EmitType.webrtcError, createWebRtcError(FailCode.OPTION_ERR, '暂无可用TURN服务器'))
|
|
126
|
-
return
|
|
127
|
-
}
|
|
128
|
-
} else {
|
|
129
|
-
await this.initConfig()
|
|
130
|
-
}
|
|
131
|
-
this.initConnectConfig()
|
|
132
|
-
this.initSignalingClient()
|
|
133
|
-
this.signalingClient?.start()
|
|
134
|
-
}
|
|
135
|
-
catch (e) {
|
|
136
|
-
this.isConnected = false
|
|
137
|
-
throw e
|
|
138
|
-
}
|
|
139
|
-
finally {
|
|
140
|
-
this.isConnecting = false
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
public async reconnect(): Promise<void> {
|
|
145
|
-
this.resetConfig() // 停止当前连接
|
|
146
|
-
try {
|
|
147
|
-
await this.prepareConnection() // 重新连接
|
|
148
|
-
}
|
|
149
|
-
catch (e) {
|
|
150
|
-
Logger.error('错误信息:', `sdk调试错误日志======>`, e)
|
|
151
|
-
this.emit(EmitType.webrtcError, e)
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
initConnectConfig(initConfig: boolean = true): void {
|
|
156
|
-
if (initConfig) {
|
|
157
|
-
this.config = new WebRTCConfig(this.options)
|
|
158
|
-
}
|
|
159
|
-
// 初始化 signal 客户端与 WebRTC 客户端
|
|
160
|
-
if (this.config) {
|
|
161
|
-
this.webRTCClient = new WebRTCClient(this.config)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// 绑定 webRTCClient 事件
|
|
165
|
-
this.webRTCClient?.on(EmitType.sendOffer, (sdp: string) => this.sendOffer(sdp))
|
|
166
|
-
this.webRTCClient?.on(EmitType.sendAnswer, (sdp: string) => this.sendAnswer(sdp))
|
|
167
|
-
this.webRTCClient?.on(EmitType.sendICEMessage, (candidate: string) => this.sendICEMessage(candidate))
|
|
168
|
-
this.webRTCClient?.on(EmitType.arrayBuffer, (buffer: ArrayBuffer) => this.emit(EmitType.arrayBuffer, buffer))
|
|
169
|
-
// 绑定 webRTCClient 事件并转发至 SDK 级别
|
|
170
|
-
this.webRTCClient?.on(EmitType.streamTrack, (track: MediaStreamTrack) => {
|
|
171
|
-
Logger.debug("调试信息:", '=========> EmitType.streamTrack callback');
|
|
172
|
-
this.emit(EmitType.streamTrack, track)
|
|
173
|
-
})
|
|
174
|
-
this.webRTCClient?.on(EmitType.iceConnectionState, (state: RTCIceConnectionState) => {
|
|
175
|
-
this.emit(EmitType.iceConnectionState, state)
|
|
176
|
-
if (state === 'connected') {
|
|
177
|
-
this.isConnected = true
|
|
178
|
-
}
|
|
179
|
-
})
|
|
180
|
-
this.webRTCClient?.on(EmitType.cloudStatusChanged, (info: CloudStatusPayload) =>
|
|
181
|
-
this.emit(EmitType.cloudStatusChanged, info),
|
|
182
|
-
)
|
|
183
|
-
this.webRTCClient?.on(EmitType.cloudClipData, (clipData: string) =>
|
|
184
|
-
this.emit(EmitType.cloudClipData, clipData),
|
|
185
|
-
)
|
|
186
|
-
this.webRTCClient?.on(EmitType.webrtcError, (err: WebRtcError) => {
|
|
187
|
-
if (err.code === FailCode.ICE_STATE && this.connectCount < this.MAX_COUNT && this.isConnected) {
|
|
188
|
-
this.connectCount++
|
|
189
|
-
this.emit(EmitType.reconnect)
|
|
190
|
-
this.reconnect()
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
Logger.error('错误信息:', `sdk调试错误日志======>`, err)
|
|
194
|
-
this.emit(EmitType.webrtcError, err)
|
|
195
|
-
}
|
|
196
|
-
})
|
|
197
|
-
this.webRTCClient?.on(EmitType.cameraError, (err: CameraError) => {
|
|
198
|
-
this.emit(EmitType.cameraError, err)
|
|
199
|
-
})
|
|
200
|
-
this.webRTCClient?.on(EmitType.statisticInfo, (info: ScreenStats) => {
|
|
201
|
-
this.emit(EmitType.statisticInfo, info)
|
|
202
|
-
})
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
initSignalingClient(): void {
|
|
206
|
-
if (this.config) {
|
|
207
|
-
this.signalingClient = new SignalingClient(this.config)
|
|
208
|
-
|
|
209
|
-
// 绑定 signalingClient 事件
|
|
210
|
-
this.signalingClient.on(EmitType.signalMessage, (message: any) => this.handleSignaling(message))
|
|
211
|
-
this.signalingClient.on(EmitType.webrtcError, (err: WebRtcError) => {
|
|
212
|
-
Logger.error('错误信息:', `sdk 信令调试错误日志======>`, err)
|
|
213
|
-
this.emit(EmitType.webrtcError, err)
|
|
214
|
-
})
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
public switchControl(roomId: string, connectorType: ConnectorType): void {
|
|
219
|
-
this.signalingClient?.sendSwitchControlMessage(roomId, connectorType)
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
public updateConfig(options: WebRTCConfigOptions) {
|
|
223
|
-
if (this.config) {
|
|
224
|
-
this.config.roomId = options.roomId
|
|
225
|
-
this.config.mainRoomIdOfGroup = options.mainRoomIdOfGroup
|
|
226
|
-
this.config.subRoomIdsOfGroup = options.subRoomIdsOfGroup
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
public switchControlToMain(roomId: string): void {
|
|
231
|
-
this.webRTCClient?.closeConnection()
|
|
232
|
-
this.webRTCClient = null
|
|
233
|
-
this.initConnectConfig(false)
|
|
234
|
-
this.signalingClient?.sendSwitchControlToMainMessage(roomId)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
public resetConfig(): void {
|
|
238
|
-
this.sendSignOut()
|
|
239
|
-
this.signalingClient?.close()
|
|
240
|
-
this.webRTCClient?.closeConnection()
|
|
241
|
-
this.signalingClient = null
|
|
242
|
-
this.webRTCClient = null
|
|
243
|
-
this.config = null
|
|
244
|
-
this.isConnected = false
|
|
245
|
-
this.isConnecting = false
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
/** 停止连接,并发送退出信令 */
|
|
249
|
-
public stop(): void {
|
|
250
|
-
this.sendSignOut()
|
|
251
|
-
this.signalingClient?.close()
|
|
252
|
-
this.webRTCClient?.closeConnection()
|
|
253
|
-
this.removeAllListeners()
|
|
254
|
-
this.signalingClient = null
|
|
255
|
-
this.webRTCClient = null
|
|
256
|
-
this.config = null
|
|
257
|
-
this.connectCount = 0
|
|
258
|
-
this.isConnected = false
|
|
259
|
-
this.isConnecting = false
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/** 开始推流:触发媒体采集与轨道添加 */
|
|
263
|
-
public async startPush(): Promise<void> {
|
|
264
|
-
try {
|
|
265
|
-
await this.webRTCClient?.startPush()
|
|
266
|
-
}
|
|
267
|
-
catch (error) {
|
|
268
|
-
let errorMessage: string
|
|
269
|
-
if (error instanceof Error) {
|
|
270
|
-
errorMessage = error.message // ✅ 只取 message
|
|
271
|
-
}
|
|
272
|
-
else {
|
|
273
|
-
errorMessage = String(error) // 兜底,防止 err 不是 Error 类型
|
|
274
|
-
}
|
|
275
|
-
this.emit(
|
|
276
|
-
EmitType.cameraError,
|
|
277
|
-
createCameraError(CameraFailCode.CAMERA_STREAM_FAIL, errorMessage),
|
|
278
|
-
)
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
public async startPushLocal(file: File): Promise<void> {
|
|
283
|
-
try {
|
|
284
|
-
await this.webRTCClient?.startPushLocal(file)
|
|
285
|
-
}
|
|
286
|
-
catch (error) {
|
|
287
|
-
let errorMessage: string
|
|
288
|
-
if (error instanceof Error) {
|
|
289
|
-
errorMessage = error.message // ✅ 只取 message
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
errorMessage = String(error) // 兜底,防止 err 不是 Error 类型
|
|
293
|
-
}
|
|
294
|
-
this.emit(
|
|
295
|
-
EmitType.cameraError,
|
|
296
|
-
createCameraError(CameraFailCode.LOCAL_STREAM_FAIL, errorMessage),
|
|
297
|
-
)
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
public stopPush() {
|
|
302
|
-
this.webRTCClient?.stopPush()
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
public stopPushLocal() {
|
|
306
|
-
this.webRTCClient?.stopLocal()
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/** 发送信道数据 */
|
|
310
|
-
public sendChannelData(type: ChannelDataType, data: any): void {
|
|
311
|
-
this.webRTCClient?.sendChannelData(type, data)
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
public sendControlEvent(key: number) {
|
|
315
|
-
const keyEvent = new KeyEventData(key, 0)
|
|
316
|
-
this.webRTCClient?.sendChannelData(ChannelDataType.ActionInput, keyEvent)
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
public sendGroupAcceptControl(roomIds: string[], acceptControl: boolean) {
|
|
320
|
-
this.signalingClient?.sendGroupAcceptControl(roomIds, acceptControl)
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* 处理 signal 消息,根据不同消息类型分发到 webRTCClient 或直接触发 SDK 事件
|
|
325
|
-
* @param message 信令消息
|
|
326
|
-
*/
|
|
327
|
-
private handleSignaling = (message: any): void => {
|
|
328
|
-
if (!this.config) return
|
|
329
|
-
Logger.debug("调试信息:", `信令消息=========>`, message);
|
|
330
|
-
switch (message.type) {
|
|
331
|
-
case MessageType.Peers:
|
|
332
|
-
this.config.myId = message.myId
|
|
333
|
-
break
|
|
334
|
-
case MessageType.Offer:
|
|
335
|
-
if (message.senderId && message.sdp) {
|
|
336
|
-
this.config.targetId = message.senderId
|
|
337
|
-
this.webRTCClient?.handleOffer(message.sdp)
|
|
338
|
-
}
|
|
339
|
-
break
|
|
340
|
-
case MessageType.Answer:
|
|
341
|
-
if (message.sdp) {
|
|
342
|
-
this.webRTCClient?.handleAnswer(message.sdp)
|
|
343
|
-
}
|
|
344
|
-
break
|
|
345
|
-
case MessageType.IceCandidates:
|
|
346
|
-
if (message.ice) {
|
|
347
|
-
try {
|
|
348
|
-
const candidateObj = JSON.parse(message.ice)
|
|
349
|
-
// 将 sdp 字段赋值给 candidate
|
|
350
|
-
candidateObj.candidate = candidateObj.sdp
|
|
351
|
-
this.webRTCClient?.handleIceCandidate(new RTCIceCandidate(candidateObj))
|
|
352
|
-
}
|
|
353
|
-
catch (error) {
|
|
354
|
-
this.emit('error', { type: 'iceCandidate', error })
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
break
|
|
358
|
-
case MessageType.SignOut:
|
|
359
|
-
if (message.myId === this.config.myId) {
|
|
360
|
-
this.webRTCClient?.closeConnection()
|
|
361
|
-
this.signalingClient?.close()
|
|
362
|
-
this.removeAllListeners()
|
|
363
|
-
}
|
|
364
|
-
break
|
|
365
|
-
case MessageType.NotAvailable:
|
|
366
|
-
this.emit(EmitType.webrtcError, createWebRtcError(FailCode.NOT_AVAILABLE, ''))
|
|
367
|
-
break
|
|
368
|
-
case MessageType.Ping:
|
|
369
|
-
this.sendPong()
|
|
370
|
-
break
|
|
371
|
-
case MessageType.SendScreenshot: {
|
|
372
|
-
const base64Str: string = message.screenshot
|
|
373
|
-
const roomId: string = message.roomId
|
|
374
|
-
this.emit(EmitType.screenshot, { roomId: roomId, base64: base64Str })
|
|
375
|
-
break
|
|
376
|
-
}
|
|
377
|
-
case MessageType.KickOut:
|
|
378
|
-
this.emit(EmitType.webrtcError, createWebRtcError(FailCode.KICK_OUT_ERR, ''))
|
|
379
|
-
break
|
|
380
|
-
case MessageType.Error:
|
|
381
|
-
if (message.error.includes('云手机没有就绪')) {
|
|
382
|
-
if (this.options.signAgain) {
|
|
383
|
-
this.signalingClient?.close()
|
|
384
|
-
this.signalingClient = null
|
|
385
|
-
this.initSignalingClient()
|
|
386
|
-
this.clearTimer()
|
|
387
|
-
this.timeout = setTimeout(() => {
|
|
388
|
-
this.signalingClient?.start()
|
|
389
|
-
}, 3000)
|
|
390
|
-
this.options.signAgain = false
|
|
391
|
-
}
|
|
392
|
-
else {
|
|
393
|
-
this.emit(EmitType.webrtcError, createWebRtcError(FailCode.NOT_AVAILABLE, ''))
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
else if (message.error.includes('token 验证失败')) {
|
|
397
|
-
this.emit(EmitType.webrtcError, createWebRtcError(FailCode.AUTH_FAILED, ''))
|
|
398
|
-
}
|
|
399
|
-
break
|
|
400
|
-
case MessageType.GroupPeersMessage:
|
|
401
|
-
this.config.roomId = message.mainRoomIdOfGroup
|
|
402
|
-
this.config.mainCloudMyId = message.mainCloudMyId
|
|
403
|
-
this.config.myId = message.myId
|
|
404
|
-
this.config.groupId = message.groupId
|
|
405
|
-
this.config.connectorAndRoomId = new Map(Object.entries(message.connectorAndRoomId))
|
|
406
|
-
this.config.connectorAndRoomId?.set(this.config.roomId, this.config.mainCloudMyId ?? '')
|
|
407
|
-
break
|
|
408
|
-
default:
|
|
409
|
-
|
|
410
|
-
break
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
clearTimer = () => {
|
|
415
|
-
if (this.timeout) {
|
|
416
|
-
clearTimeout(this.timeout)
|
|
417
|
-
this.timeout = null
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
/** 发送 Offer 信令 */
|
|
422
|
-
sendOffer = (offerSdp: string): void => {
|
|
423
|
-
if (!this.config) return
|
|
424
|
-
if (offerSdp && offerSdp.length > 0) {
|
|
425
|
-
const groupModeTargetId = this.config.connectorAndRoomId?.get(this.config.roomId) ?? ''
|
|
426
|
-
let targetId = this.config.targetId
|
|
427
|
-
if (groupModeTargetId) {
|
|
428
|
-
targetId = groupModeTargetId
|
|
429
|
-
}
|
|
430
|
-
const message = {
|
|
431
|
-
type: SendType.Offer,
|
|
432
|
-
identity: SendType.Identity,
|
|
433
|
-
roomId: this.config.roomId,
|
|
434
|
-
senderId: this.config.myId,
|
|
435
|
-
targetId: targetId,
|
|
436
|
-
sdp: offerSdp,
|
|
437
|
-
}
|
|
438
|
-
this.signalingClient?.sendMessage(JSON.stringify(message))
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
/** 发送 Answer 信令 */
|
|
443
|
-
sendAnswer = (answerSdp: string): void => {
|
|
444
|
-
if (!this.config) return
|
|
445
|
-
if (answerSdp && answerSdp.length > 0) {
|
|
446
|
-
const groupModeTargetId = this.config.connectorAndRoomId?.get(this.config.roomId) ?? ''
|
|
447
|
-
let targetId = this.config.targetId
|
|
448
|
-
if (groupModeTargetId) {
|
|
449
|
-
targetId = groupModeTargetId
|
|
450
|
-
}
|
|
451
|
-
const message = {
|
|
452
|
-
traceId: this.config.traceId,
|
|
453
|
-
type: SendType.Answer,
|
|
454
|
-
identity: SendType.Identity,
|
|
455
|
-
roomId: this.config.roomId,
|
|
456
|
-
senderId: this.config.myId,
|
|
457
|
-
targetId: targetId,
|
|
458
|
-
sdp: answerSdp,
|
|
459
|
-
}
|
|
460
|
-
this.signalingClient?.sendMessage(JSON.stringify(message))
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
/** 发送 ICE 候选信息 */
|
|
465
|
-
sendICEMessage = (ice: string): void => {
|
|
466
|
-
if (!this.config) return
|
|
467
|
-
const groupModeTargetId = this.config.connectorAndRoomId?.get(this.config.roomId) ?? ''
|
|
468
|
-
let targetId = this.config.targetId
|
|
469
|
-
if (groupModeTargetId) {
|
|
470
|
-
targetId = groupModeTargetId
|
|
471
|
-
}
|
|
472
|
-
if (ice && ice.length > 0) {
|
|
473
|
-
const message = {
|
|
474
|
-
traceId: this.config.traceId,
|
|
475
|
-
type: SendType.IceCandidates,
|
|
476
|
-
identity: SendType.Identity,
|
|
477
|
-
roomId: this.config.roomId,
|
|
478
|
-
senderId: this.config.myId,
|
|
479
|
-
targetId: targetId,
|
|
480
|
-
ice,
|
|
481
|
-
}
|
|
482
|
-
this.signalingClient?.sendMessage(JSON.stringify(message))
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
sendPong() {
|
|
487
|
-
const message = {
|
|
488
|
-
type: SendType.Pong,
|
|
489
|
-
}
|
|
490
|
-
const jsonMessage = JSON.stringify(message)
|
|
491
|
-
this.signalingClient?.sendMessage(jsonMessage)
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
sendSignOut() {
|
|
495
|
-
if (!this.config) return
|
|
496
|
-
if (this.config.connectorType === ConnectorType.LanForwarding) {
|
|
497
|
-
const message = {
|
|
498
|
-
type: SendType.GroupSignOut,
|
|
499
|
-
identity: SendType.Identity,
|
|
500
|
-
token: this.config.token,
|
|
501
|
-
groupId: this.config.groupId,
|
|
502
|
-
}
|
|
503
|
-
this.signalingClient?.sendMessage(JSON.stringify(message))
|
|
504
|
-
}
|
|
505
|
-
else {
|
|
506
|
-
const message = {
|
|
507
|
-
type: SendType.SignOut,
|
|
508
|
-
identity: SendType.Identity,
|
|
509
|
-
roomId: this.config.roomId,
|
|
510
|
-
myId: this.config.myId,
|
|
511
|
-
}
|
|
512
|
-
this.signalingClient?.sendMessage(JSON.stringify(message))
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
public groupSendAction(type: ChannelDataType, data: any): void {
|
|
517
|
-
try {
|
|
518
|
-
let actionData: ChannelData | null = null
|
|
519
|
-
switch (type) {
|
|
520
|
-
case ChannelDataType.ClickData:
|
|
521
|
-
actionData = ChannelData.click(data)
|
|
522
|
-
Logger.debug('群控控制事件===>', `Grp=${data.groupIndex}, Idx=${data.index}, action=${data.action}, time=${formattedTime(Date.now())}`)
|
|
523
|
-
break
|
|
524
|
-
case ChannelDataType.ClipboardData:
|
|
525
|
-
actionData = ChannelData.clipboard(data)
|
|
526
|
-
break
|
|
527
|
-
case ChannelDataType.ActionInput:
|
|
528
|
-
actionData = ChannelData.input(data, this.config?.myId ?? '')
|
|
529
|
-
break
|
|
530
|
-
case ChannelDataType.ActionChinese:
|
|
531
|
-
actionData = ChannelData.chinese(data)
|
|
532
|
-
break
|
|
533
|
-
case ChannelDataType.ActionRequestCloudDeviceInfo:
|
|
534
|
-
actionData = ChannelData.requestCloudDeviceInfo()
|
|
535
|
-
break
|
|
536
|
-
case ChannelDataType.ActionClarity:
|
|
537
|
-
actionData = ChannelData.clarity(data)
|
|
538
|
-
break
|
|
539
|
-
case ChannelDataType.ActionWheel:
|
|
540
|
-
actionData = ChannelData.wheel(data)
|
|
541
|
-
break
|
|
542
|
-
case ChannelDataType.ActionGesture:
|
|
543
|
-
actionData = ChannelData.gesture(data)
|
|
544
|
-
break
|
|
545
|
-
case ChannelDataType.ActionCommand:
|
|
546
|
-
actionData = ChannelData.action(data)
|
|
547
|
-
break
|
|
548
|
-
case ChannelDataType.ActionCommandEvent:
|
|
549
|
-
actionData = ChannelData.switchAudio(data)
|
|
550
|
-
break
|
|
551
|
-
}
|
|
552
|
-
if (actionData) {
|
|
553
|
-
const jsonString = JSON.stringify(actionData)
|
|
554
|
-
this.signalingClient?.sendGroupAction(jsonString)
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
catch (err) {
|
|
558
|
-
this.emit(EmitType.webrtcError, createWebRtcError(FailCode.DATACHANNEL_ERR, err))
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
export enum MessageType {
|
|
2
|
-
Peers = 'Peers',
|
|
3
|
-
Offer = 'Offer',
|
|
4
|
-
Answer = 'Answer',
|
|
5
|
-
IceCandidates = 'IceCandidates',
|
|
6
|
-
SignOut = 'SignOut',
|
|
7
|
-
NotAvailable = 'NotAvailable',
|
|
8
|
-
Ping = 'Ping',
|
|
9
|
-
Pong = 'Pong',
|
|
10
|
-
SendScreenshot = 'SendScreenshot',
|
|
11
|
-
KickOut = 'KickOut',
|
|
12
|
-
GroupPeersMessage = 'GroupPeer',
|
|
13
|
-
Error = 'Error',
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export enum SendType {
|
|
17
|
-
SignIn = 'SignIn',
|
|
18
|
-
SignOut = 'SignOut',
|
|
19
|
-
Answer = 'Answer',
|
|
20
|
-
Offer = 'Offer',
|
|
21
|
-
IceCandidates = 'IceCandidates',
|
|
22
|
-
Pong = 'Pong',
|
|
23
|
-
Identity = 'Web',
|
|
24
|
-
SwitchControl = 'SwitchControl',
|
|
25
|
-
GroupSignIn = 'GroupSignIn',
|
|
26
|
-
GroupSignOut = 'GroupSignOut',
|
|
27
|
-
GroupSendAction = 'GroupSendAction',
|
|
28
|
-
SwitchControlToMain = 'SwitchControlToMain',
|
|
29
|
-
GroupAcceptControl = 'GroupAcceptControl',
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 标识自己以什么类型连接云机
|
|
34
|
-
* 内网转发类型中,主从切换由config中mainRoomIdOfGroup, subRoomIdsOfGroup控制
|
|
35
|
-
* 非内网转发类型中,主从切换由config中connectorType控制
|
|
36
|
-
*/
|
|
37
|
-
export enum ConnectorType {
|
|
38
|
-
/**
|
|
39
|
-
* 主控类型
|
|
40
|
-
* 页面展示: WebRTC
|
|
41
|
-
* 数据通道: WebRTC dataChannel
|
|
42
|
-
*/
|
|
43
|
-
WebRTC = 'webrtc',
|
|
44
|
-
/**
|
|
45
|
-
* 内网转发类型
|
|
46
|
-
* 主控
|
|
47
|
-
* 页面展示: WebRTC
|
|
48
|
-
* 数据通道: WebRTC dataChannel
|
|
49
|
-
* 从控
|
|
50
|
-
* 页面展示: Websocket
|
|
51
|
-
* 数据通道: Websocket
|
|
52
|
-
*/
|
|
53
|
-
LanForwarding = 'lanForwarding',
|
|
54
|
-
/**
|
|
55
|
-
* 混合-从控类型
|
|
56
|
-
* 页面展示: Websocket
|
|
57
|
-
* 数据通道: WebRTC dataChannel
|
|
58
|
-
*/
|
|
59
|
-
Hybrid = 'hybrid',
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export enum IceConnectionState {
|
|
63
|
-
NEW = 'new',
|
|
64
|
-
CHECKING = 'checking',
|
|
65
|
-
CONNECTED = 'connected',
|
|
66
|
-
COMPLETED = 'completed',
|
|
67
|
-
DISCONNECTED = 'disconnected',
|
|
68
|
-
FAILED = 'failed',
|
|
69
|
-
CLOSED = 'closed',
|
|
70
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export type TurnServerConfig = {
|
|
2
|
-
urls: string
|
|
3
|
-
username?: string
|
|
4
|
-
credential?: string
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface TurnTestResult extends TurnServerConfig {
|
|
8
|
-
rtt: number // Infinity 表示失败
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export type PublicTurnTestResult = {
|
|
12
|
-
urls: string
|
|
13
|
-
rtt: number
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type TurnTestSummary = {
|
|
17
|
-
best?: PublicTurnTestResult
|
|
18
|
-
all: PublicTurnTestResult[]
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface TurnSelectionResult {
|
|
22
|
-
url?: string
|
|
23
|
-
rtt?: number
|
|
24
|
-
error?: string
|
|
25
|
-
}
|