@threejs-shared/protobuf 0.1.3 → 0.1.5

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.
@@ -1,103 +0,0 @@
1
- type FrameDataCallback = (frameData: Array<{ id: number; value: number }>) => void
2
- type Callback = (args?: any) => void
3
-
4
- export class TimerManager {
5
- private dataArray: Array<{ id: number; value: number }> // 数据数组
6
- private frameSize: number // 每帧返回的数据量
7
- private interval: number // 每帧的时间间隔(毫秒)
8
- private currentIndex: number // 当前帧的起始索引
9
- private timer: ReturnType<typeof setInterval> | null // 定时器句柄
10
- isPaused: Boolean // 是否暂停
11
- private onFrame: (params: any) => void // 是否暂停
12
- private onComplete: Callback // 播放完成时回调函数,是否暂停
13
- private onProcess: Callback // 播放过程中回调函数
14
-
15
- constructor(dataArray = [], interval = 50, frameSize = 1) {
16
- this.dataArray = dataArray
17
- this.frameSize = frameSize
18
- this.interval = interval
19
- this.currentIndex = 0
20
- this.timer = null
21
- this.isPaused = false
22
- this.onFrame = () => {
23
- console.log('Frame updated')
24
- }
25
- this.onComplete = () => {
26
- console.log('Timer complete')
27
- }
28
- this.onProcess = (args?: any) => {
29
- console.log('Timer process', args)
30
- }
31
- }
32
- // 开始模拟 WebSocket 数据发送
33
- public connect(onFrame: FrameDataCallback, onProcess?: Callback, onComplete?: Callback): void {
34
- this.onFrame = onFrame || this.onFrame
35
- this.onProcess = onProcess || this.onProcess
36
- this.onComplete = onComplete || this.onComplete
37
- if (this.timer) {
38
- console.warn('Simulation is already running.')
39
- return
40
- }
41
- this.start()
42
- }
43
- public start(): void {
44
- const processFrame = () => {
45
- if (this.isPaused) return // 如果暂停,跳过处理
46
- if (this.currentIndex >= this.dataArray.length) {
47
- this.stop() // 停止定时器
48
- if (this.onComplete) this.onComplete() // 调用完成回调
49
- return
50
- }
51
- const frameData: any = this.dataArray.slice(this.currentIndex, this.currentIndex + this.frameSize) // 获取当前帧数据
52
- this.currentIndex += this.frameSize // 更新索引
53
- this.onFrame(frameData[0]) // 调用帧数据处理回调
54
-
55
- const currentSecond = Math.floor(this.currentIndex / this.interval)
56
- this.onProcess?.(currentSecond)
57
- }
58
-
59
- this.timer && clearInterval(this.timer)
60
- this.timer = setInterval(processFrame, 1000 / this.interval)
61
- }
62
- public startFrom(startSecond: number = 0) {
63
- this.currentIndex = startSecond * this.interval
64
- // this.isPaused = false
65
- this.start()
66
- }
67
- // 停止模拟
68
- public stop(): void {
69
- if (this.timer) {
70
- clearInterval(this.timer)
71
- this.timer = null
72
- this.isPaused = true
73
- console.log('Simulation stopped.')
74
- }
75
- }
76
- // 重置模拟器(可重新开始)
77
- public reset(): void {
78
- this.stop()
79
- this.currentIndex = 0
80
- this.isPaused = false
81
- this.start()
82
- console.log('Simulation reset.')
83
- }
84
- // 暂停模拟
85
- public pause(): void {
86
- if (this.timer) {
87
- this.isPaused = true // 设置暂停状态
88
- // console.log('Simulation paused.')
89
- } else {
90
- console.warn('Simulation is not running. Cannot pause.')
91
- }
92
- }
93
-
94
- // 继续模拟
95
- public resume(): void {
96
- if (this.timer && this.isPaused) {
97
- this.isPaused = false // 恢复非暂停状态
98
- // console.log('Simulation resumed.')
99
- } else {
100
- console.warn('Simulation is not running or already resumed.')
101
- }
102
- }
103
- }
@@ -1,352 +0,0 @@
1
- import type { ProtobufType } from './types'
2
-
3
- /**
4
- * WebSocket 连接状态
5
- */
6
- export enum WebSocketStatus {
7
- CONNECTING = 'CONNECTING',
8
- CONNECTED = 'CONNECTED',
9
- DISCONNECTING = 'DISCONNECTING',
10
- DISCONNECTED = 'DISCONNECTED',
11
- ERROR = 'ERROR'
12
- }
13
-
14
- /**
15
- * 消息发送格式
16
- */
17
- export enum MessageFormat {
18
- /** JSON 格式 */
19
- JSON = 'JSON',
20
- /** Protobuf 二进制格式 */
21
- PROTOBUF = 'PROTOBUF',
22
- /** 原始字符串格式 */
23
- STRING = 'STRING'
24
- }
25
-
26
- /**
27
- * WebSocket 管理器配置选项
28
- */
29
- export interface WebSocketManagerOptions {
30
- /** 是否启用自动重连 */
31
- autoReconnect?: boolean
32
- /** 重连延迟时间(毫秒) */
33
- reconnectDelay?: number
34
- /** 最大重连次数 */
35
- maxReconnectAttempts?: number
36
- /** 是否启用日志 */
37
- enableLog?: boolean
38
- }
39
-
40
- /**
41
- * WebSocket 事件回调
42
- */
43
- export interface WebSocketCallbacks {
44
- /** 连接打开时的回调 */
45
- onOpen?: () => void
46
- /** 接收到消息时的回调 */
47
- onMessage?: (data: any) => void
48
- /** 连接错误时的回调 */
49
- onError?: (error: Event) => void
50
- /** 连接关闭时的回调 */
51
- onClose?: (event: CloseEvent) => void
52
- /** 重连时的回调 */
53
- onReconnect?: (attempt: number) => void
54
- }
55
-
56
- /**
57
- * WebSocket 管理器,用于管理基于 Protobuf 的 WebSocket 连接
58
- */
59
- export class WebSocketManager {
60
- private socket: WebSocket | null = null
61
- private MessagePb: ProtobufType | null = null
62
- private wsUrl: string
63
- private status: WebSocketStatus = WebSocketStatus.DISCONNECTED
64
- private reconnectAttempts = 0
65
- private reconnectTimer: ReturnType<typeof setTimeout> | null = null
66
- private options: Required<WebSocketManagerOptions>
67
- private callbacks: WebSocketCallbacks = {}
68
-
69
- constructor(wsUrl: string, protobufType: ProtobufType, options?: WebSocketManagerOptions) {
70
- this.wsUrl = wsUrl
71
- this.MessagePb = protobufType
72
- this.options = {
73
- autoReconnect: options?.autoReconnect ?? false,
74
- reconnectDelay: options?.reconnectDelay ?? 3000,
75
- maxReconnectAttempts: options?.maxReconnectAttempts ?? 5,
76
- enableLog: options?.enableLog ?? true
77
- }
78
- }
79
-
80
- /**
81
- * 连接 WebSocket
82
- * @param callbacks 事件回调
83
- */
84
- connect(callbacks?: WebSocketCallbacks): void {
85
- if (this.socket && this.status === WebSocketStatus.CONNECTED) {
86
- this.log('WebSocket is already connected')
87
- return
88
- }
89
-
90
- // 保存回调
91
- if (callbacks) {
92
- this.callbacks = { ...this.callbacks, ...callbacks }
93
- }
94
-
95
- // 清理之前的连接
96
- this.cleanup()
97
- try {
98
- this.status = WebSocketStatus.CONNECTING
99
- this.socket = new WebSocket(this.wsUrl)
100
- this.setupEventListeners()
101
- } catch (error) {
102
- this.status = WebSocketStatus.ERROR
103
- this.log('Failed to create WebSocket:', error)
104
- this.callbacks.onError?.(error as Event)
105
- throw error
106
- }
107
- }
108
-
109
- /**
110
- * 设置事件监听器
111
- */
112
- private setupEventListeners(): void {
113
- if (!this.socket) return
114
-
115
- this.socket.addEventListener('open', () => {
116
- this.status = WebSocketStatus.CONNECTED
117
- this.reconnectAttempts = 0
118
- this.log('WebSocket connected')
119
- this.callbacks.onOpen?.()
120
- })
121
-
122
- this.socket.addEventListener('message', async (event: MessageEvent) => {
123
- if (!this.MessagePb) {
124
- this.log('Protobuf type is not set')
125
- return
126
- }
127
-
128
- try {
129
- const blob = event.data
130
- const buffer = await blob.arrayBuffer()
131
- const data = new Uint8Array(buffer)
132
- const receivedMessage = this.MessagePb.decode(data)
133
- this.callbacks.onMessage?.(receivedMessage)
134
- } catch (error) {
135
- this.log('Failed to decode message:', error)
136
- this.callbacks.onError?.(error as Event)
137
- }
138
- })
139
-
140
- this.socket.addEventListener('error', (error: Event) => {
141
- this.status = WebSocketStatus.ERROR
142
- this.log('WebSocket error:', error)
143
- this.callbacks.onError?.(error)
144
-
145
- // 如果启用了自动重连,尝试重连
146
- if (this.options.autoReconnect && this.reconnectAttempts < this.options.maxReconnectAttempts) {
147
- this.scheduleReconnect()
148
- }
149
- })
150
-
151
- this.socket.addEventListener('close', (event: CloseEvent) => {
152
- this.status = WebSocketStatus.DISCONNECTED
153
- this.log('WebSocket closed', { code: event.code, reason: event.reason })
154
- this.callbacks.onClose?.(event)
155
-
156
- // 如果启用了自动重连且不是主动关闭,尝试重连
157
- if (
158
- this.options.autoReconnect &&
159
- this.reconnectAttempts < this.options.maxReconnectAttempts &&
160
- event.code !== 1000 // 1000 表示正常关闭
161
- ) {
162
- this.scheduleReconnect()
163
- }
164
- })
165
- }
166
-
167
- /**
168
- * 发送消息
169
- * @param message 要发送的消息对象或字符串
170
- * @param format 消息格式,默认为 Protobuf 格式
171
- * @throws 如果连接未建立或消息验证失败
172
- */
173
- send(message: object | string, format: MessageFormat = MessageFormat.PROTOBUF): void {
174
- if (!this.socket || this.status !== WebSocketStatus.CONNECTED) {
175
- throw new Error('WebSocket is not connected')
176
- }
177
-
178
- try {
179
- if (format === MessageFormat.STRING) {
180
- // 原始字符串格式发送,直接发送字符串
181
- if (typeof message !== 'string') {
182
- throw new Error('STRING format requires a string message')
183
- }
184
- this.socket.send(message)
185
- this.log('Message sent (STRING):', message)
186
- } else if (format === MessageFormat.JSON) {
187
- // JSON 格式发送
188
- if (typeof message === 'string') {
189
- // 如果是字符串,直接发送(假设已经是 JSON 字符串)
190
- this.socket.send(message)
191
- this.log('Message sent (JSON):', message)
192
- } else {
193
- // 如果是对象,序列化为 JSON 字符串
194
- const jsonString = JSON.stringify(message)
195
- this.socket.send(jsonString)
196
- this.log('Message sent (JSON):', message)
197
- }
198
- } else {
199
- // Protobuf 格式发送
200
- if (!this.MessagePb) {
201
- throw new Error('Protobuf type is not set')
202
- }
203
-
204
- // 如果传入的是字符串,解析为对象
205
- let messageObj: object
206
- if (typeof message === 'string') {
207
- try {
208
- messageObj = JSON.parse(message)
209
- } catch (error) {
210
- throw new Error(`Invalid JSON string for Protobuf: ${error}`)
211
- }
212
- } else {
213
- messageObj = message
214
- }
215
-
216
- // 验证数据是否符合 Protobuf 定义
217
- const errMsg = this.MessagePb.verify(messageObj)
218
- if (errMsg) {
219
- throw new Error(`Message verification failed: ${errMsg}`)
220
- }
221
-
222
- // 创建 Protobuf 消息
223
- const msg = this.MessagePb.create(messageObj)
224
-
225
- // 序列化消息为二进制格式
226
- const buffer = this.MessagePb.encode(msg).finish()
227
-
228
- // 通过 WebSocket 发送二进制数据
229
- this.socket.send(buffer)
230
- this.log('Message sent (Protobuf):', messageObj)
231
- }
232
- } catch (error) {
233
- this.log('Failed to send message:', error)
234
- throw error
235
- }
236
- }
237
-
238
- /**
239
- * 断开连接
240
- * @param code 关闭代码
241
- * @param reason 关闭原因
242
- */
243
- disconnect(code?: number, reason?: string): void {
244
- if (this.socket) {
245
- this.status = WebSocketStatus.DISCONNECTING
246
- this.socket.close(code ?? 1000, reason)
247
- this.cleanup()
248
- this.status = WebSocketStatus.DISCONNECTED
249
- }
250
- }
251
-
252
- /**
253
- * 获取当前连接状态
254
- */
255
- getStatus(): WebSocketStatus {
256
- return this.status
257
- }
258
-
259
- /**
260
- * 检查是否已连接
261
- */
262
- isConnected(): boolean {
263
- return this.status === WebSocketStatus.CONNECTED &&
264
- this.socket?.readyState === WebSocket.OPEN
265
- }
266
-
267
- /**
268
- * 设置 Protobuf 类型
269
- */
270
- setProtobufType(protobufType: ProtobufType): void {
271
- this.MessagePb = protobufType
272
- }
273
-
274
- /**
275
- * 更新回调函数
276
- */
277
- updateCallbacks(callbacks: WebSocketCallbacks): void {
278
- this.callbacks = { ...this.callbacks, ...callbacks }
279
- }
280
-
281
- /**
282
- * 计划重连
283
- */
284
- private scheduleReconnect(): void {
285
- if (this.reconnectTimer) {
286
- clearTimeout(this.reconnectTimer)
287
- }
288
-
289
- this.reconnectAttempts++
290
- this.log(`Scheduling reconnect attempt ${this.reconnectAttempts}/${this.options.maxReconnectAttempts}`)
291
-
292
- this.callbacks.onReconnect?.(this.reconnectAttempts)
293
-
294
- this.reconnectTimer = setTimeout(() => {
295
- this.log(`Reconnecting... (attempt ${this.reconnectAttempts})`)
296
- try {
297
- this.socket = new WebSocket(this.wsUrl)
298
- this.setupEventListeners()
299
- } catch (error) {
300
- this.log('Reconnect failed:', error)
301
- if (this.reconnectAttempts < this.options.maxReconnectAttempts) {
302
- this.scheduleReconnect()
303
- }
304
- }
305
- }, this.options.reconnectDelay)
306
- }
307
-
308
- /**
309
- * 清理资源
310
- */
311
- private cleanup(): void {
312
- if (this.reconnectTimer) {
313
- clearTimeout(this.reconnectTimer)
314
- this.reconnectTimer = null
315
- }
316
-
317
- if (this.socket) {
318
- // 移除所有事件监听器
319
- this.socket.onopen = null
320
- this.socket.onmessage = null
321
- this.socket.onerror = null
322
- this.socket.onclose = null
323
-
324
- // 如果连接还在,关闭它
325
- if (this.socket.readyState === WebSocket.OPEN ||
326
- this.socket.readyState === WebSocket.CONNECTING) {
327
- this.socket.close()
328
- }
329
-
330
- this.socket = null
331
- }
332
- }
333
-
334
- /**
335
- * 日志输出
336
- */
337
- private log(...args: any[]): void {
338
- if (this.options.enableLog) {
339
- console.log('[WebSocketManager]', ...args)
340
- }
341
- }
342
-
343
- /**
344
- * 销毁实例,清理所有资源
345
- */
346
- destroy(): void {
347
- this.disconnect()
348
- this.callbacks = {}
349
- this.MessagePb = null
350
- this.reconnectAttempts = 0
351
- }
352
- }
package/src/types.ts DELETED
@@ -1,2 +0,0 @@
1
- import type { Type } from 'protobufjs'
2
- export type ProtobufType = Type