@ives_xxz/framework 2.0.12 → 2.0.14

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.
@@ -56,6 +56,7 @@ export function initializeFramework() {
56
56
  FW.Log = new (require('./log/FWLog').FWLog)();
57
57
  FW.Layer = require('./layer/FWLayer').FWLayer;
58
58
  FW.LayerController = require('./controller/FWLayerController').FWLayerController;
59
+ FW.SocketMock = new (require('./service/socket/mock/FWSocketMock').FWSocketMock)();
59
60
  FW.Framework.initialize();
60
61
  FW.Entry.initialize();
61
62
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ives_xxz/framework",
3
- "version": "2.0.12",
3
+ "version": "2.0.14",
4
4
  "description": "cocoscreator 2.x mvc framework",
5
5
  "main": "index.js",
6
6
  "keywords": ["123456"],
@@ -1,10 +1,9 @@
1
- import { FWSystemConfig } from "../../config/FWSystemConfig";
2
- import FWService from "../FWService";
1
+ import { FWSystemConfig } from '../../config/FWSystemConfig';
3
2
 
4
3
  /**
5
4
  * TODO 犹豫socket没有改版暂时已老的cmd字符串映射方式做,后期优化
6
5
  */
7
- export default class FWSocket extends FWService implements FW.Socket {
6
+ export default class FWSocket extends FW.Service implements FW.Socket {
8
7
  /** 发送心跳时间抽 */
9
8
  private sendHeartTimestamp: number;
10
9
  /** 接收心跳时间戳 */
@@ -64,7 +63,7 @@ export default class FWSocket extends FWService implements FW.Socket {
64
63
  tag: string,
65
64
  socketSender: FW.Sender,
66
65
  socketHandle: FW.Handle,
67
- config: FW.SocketConfig
66
+ config: FW.SocketConfig,
68
67
  ): FW.SocketPromiseProxy {
69
68
  try {
70
69
  FW.Entry.timeMgr.unSchedule(this);
@@ -95,7 +94,6 @@ export default class FWSocket extends FWService implements FW.Socket {
95
94
  this.socket = new WebSocket(address);
96
95
  }
97
96
  }
98
-
99
97
  this.socket.onopen = this.onSocketOpen.bind(this);
100
98
  this.socket.onclose = this.onSocketClose.bind(this);
101
99
  this.socket.onerror = this.onSocketError.bind(this);
@@ -108,14 +106,10 @@ export default class FWSocket extends FWService implements FW.Socket {
108
106
  this.heartInternal = config?.heartInternal || defaultConfig.heartInternal;
109
107
  this.heartTimeout = config?.heartTimeout || defaultConfig.heartTimeout;
110
108
  this.heartWeakTime = config?.heartWeakTime || defaultConfig.heartWeakTime;
111
- this.maxReconnectTimes =
112
- config?.maxReconnectTimes || defaultConfig.maxReconnectTimes;
113
- this.reconnectInternal =
114
- config?.reconnectInternal || defaultConfig.reconnectInternal;
115
- this.protocolSymbol =
116
- config?.protocolSymbol || defaultConfig.protocolSymbol;
117
- this.protocolPollingTime =
118
- config?.protocolPollingTime || defaultConfig.protocolPollingTime;
109
+ this.maxReconnectTimes = config?.maxReconnectTimes || defaultConfig.maxReconnectTimes;
110
+ this.reconnectInternal = config?.reconnectInternal || defaultConfig.reconnectInternal;
111
+ this.protocolSymbol = config?.protocolSymbol || defaultConfig.protocolSymbol;
112
+ this.protocolPollingTime = config?.protocolPollingTime || defaultConfig.protocolPollingTime;
119
113
 
120
114
  this.promiseProxy = {
121
115
  promise: undefined,
@@ -129,7 +123,7 @@ export default class FWSocket extends FWService implements FW.Socket {
129
123
 
130
124
  return this.promiseProxy;
131
125
  } catch (e) {
132
- FW.Log.error("创建socket失败:", e);
126
+ FW.Log.error('创建socket失败:', e);
133
127
  }
134
128
  }
135
129
  /**
@@ -195,7 +189,7 @@ export default class FWSocket extends FWService implements FW.Socket {
195
189
  if (force) this.reconnectTimes = 0;
196
190
 
197
191
  FW.Log.debug(
198
- `socket reconnect : reconnectTimes->${this.reconnectTimes},maxReconnectTimes->${this.maxReconnectTimes}`
192
+ `socket reconnect : reconnectTimes->${this.reconnectTimes},maxReconnectTimes->${this.maxReconnectTimes}`,
199
193
  );
200
194
  if (++this.reconnectTimes >= this.maxReconnectTimes) {
201
195
  this.socketHandle?.onTimeout?.();
@@ -206,22 +200,16 @@ export default class FWSocket extends FWService implements FW.Socket {
206
200
  this.socket?.close();
207
201
  this.socket = null;
208
202
 
209
- this.createSocket(
210
- this.address,
211
- this.tag,
212
- this.socketSender,
213
- this.socketHandle,
214
- {
215
- heartInternal: this.heartInternal,
216
- heartTimeout: this.heartTimeout,
217
- heartWeakTime: this.heartWeakTime,
218
- maxReconnectTimes: this.maxReconnectTimes,
219
- reconnectInternal: this.reconnectInternal,
220
- protocolSymbol: this.protocolSymbol,
221
- protocolPollingTime: this.protocolPollingTime,
222
- certificate: this.certificate,
223
- }
224
- );
203
+ this.createSocket(this.address, this.tag, this.socketSender, this.socketHandle, {
204
+ heartInternal: this.heartInternal,
205
+ heartTimeout: this.heartTimeout,
206
+ heartWeakTime: this.heartWeakTime,
207
+ maxReconnectTimes: this.maxReconnectTimes,
208
+ reconnectInternal: this.reconnectInternal,
209
+ protocolSymbol: this.protocolSymbol,
210
+ protocolPollingTime: this.protocolPollingTime,
211
+ certificate: this.certificate,
212
+ });
225
213
  }
226
214
 
227
215
  async send(msg: string) {
@@ -231,8 +219,7 @@ export default class FWSocket extends FWService implements FW.Socket {
231
219
  const protocolKey = this.socketSender.getProtocolKey?.(msg);
232
220
  if (protocolKey) {
233
221
  const symbol = Symbol(protocolKey);
234
- const registry =
235
- this.protocolRegistry.get(protocolKey) || new Set<Symbol>();
222
+ const registry = this.protocolRegistry.get(protocolKey) || new Set<Symbol>();
236
223
  const protocolPolling: FW.ProtocolPolling = {
237
224
  msg: msg,
238
225
  schedule: FW.Entry.timeMgr.schedule(
@@ -241,7 +228,7 @@ export default class FWSocket extends FWService implements FW.Socket {
241
228
  },
242
229
  this.protocolPollingTime,
243
230
  cc.macro.REPEAT_FOREVER,
244
- this
231
+ this,
245
232
  ),
246
233
  };
247
234
  this.protocolRegistry.set(protocolKey, registry.add(symbol));
@@ -253,7 +240,7 @@ export default class FWSocket extends FWService implements FW.Socket {
253
240
 
254
241
  /** 连接打开 */
255
242
  private onSocketOpen() {
256
- FW.Log.debug("on open!");
243
+ FW.Log.debug('on open!');
257
244
  FW.Entry.timeMgr.unSchedule(this);
258
245
  this.reconnectTimes = 0;
259
246
  this.sendHeartTimestamp = 0;
@@ -278,7 +265,7 @@ export default class FWSocket extends FWService implements FW.Socket {
278
265
  },
279
266
  this.heartInternal / 1000,
280
267
  cc.macro.REPEAT_FOREVER,
281
- this
268
+ this,
282
269
  );
283
270
  }
284
271
 
@@ -297,20 +284,17 @@ export default class FWSocket extends FWService implements FW.Socket {
297
284
 
298
285
  /** socket关闭 */
299
286
  private onSocketClose() {
300
- FW.Log.debug("on close!");
287
+ FW.Log.debug('on close!');
301
288
  this.socketHandle?.onClose?.();
302
289
  FW.Entry.timeMgr.scheduleOnce(
303
290
  () => {
304
- if (
305
- this.getReadyState() == WebSocket.CLOSING ||
306
- this.getReadyState() == WebSocket.CLOSED
307
- ) {
308
- FW.Log.debug("on close!");
291
+ if (this.getReadyState() == WebSocket.CLOSING || this.getReadyState() == WebSocket.CLOSED) {
292
+ FW.Log.debug('on close!');
309
293
  this.reconnect();
310
294
  }
311
295
  },
312
296
  this.reconnectInternal,
313
- this
297
+ this,
314
298
  );
315
299
  }
316
300
 
@@ -318,7 +302,7 @@ export default class FWSocket extends FWService implements FW.Socket {
318
302
  private async onSocketMessage(originalMsg: any) {
319
303
  const msg = await this.socketHandle.onBeforeReceivingMessage(originalMsg);
320
304
 
321
- if (msg.error) {
305
+ if (!msg || msg?.error) {
322
306
  this.onSocketError(msg);
323
307
  return;
324
308
  }
@@ -0,0 +1,203 @@
1
+ class MockWebSocket {
2
+ public url: string;
3
+ public readyState: number;
4
+ public binaryType: BinaryType = 'blob';
5
+
6
+ static readonly CONNECTING = 0;
7
+ static readonly OPEN = 1;
8
+ static readonly CLOSING = 2;
9
+ static readonly CLOSED = 3;
10
+
11
+ public onopen: ((event: Event) => void) | null = null;
12
+ public onmessage: ((event: MessageEvent) => void) | null = null;
13
+ public onerror: ((event: Event) => void) | null = null;
14
+ public onclose: ((event: CloseEvent) => void) | null = null;
15
+
16
+ private messageQueue: any[] = [];
17
+
18
+ constructor(url: string | URL, protocols?: string | string[]) {
19
+ this.url = url.toString();
20
+ this.readyState = MockWebSocket.CONNECTING;
21
+
22
+ FW.Entry.timeMgr.scheduleOnce(() => {
23
+ this.readyState = MockWebSocket.OPEN;
24
+
25
+ this.onopen?.(new Event('open'));
26
+
27
+ WebSocketMockServer.getInstance().addClient(this);
28
+
29
+ this.processMessageQueue();
30
+ });
31
+ }
32
+
33
+ send(data: string | ArrayBuffer | Blob | ArrayBufferView): void {
34
+ if (this.readyState !== MockWebSocket.OPEN) {
35
+ this.messageQueue.push(data);
36
+ return;
37
+ }
38
+
39
+ WebSocketMockServer.getInstance().handleMessage(this, data);
40
+ }
41
+
42
+ close(code?: number, reason?: string): void {
43
+ if (this.readyState === MockWebSocket.CLOSED) return;
44
+
45
+ this.readyState = MockWebSocket.CLOSED;
46
+ WebSocketMockServer.getInstance().removeClient(this);
47
+
48
+ const closeEvent = new CloseEvent('close', {
49
+ code: code || 1000,
50
+ reason: reason || 'Normal closure',
51
+ wasClean: true,
52
+ });
53
+
54
+ if (this.onclose) {
55
+ this.onclose(closeEvent);
56
+ }
57
+ }
58
+
59
+ private processMessageQueue(): void {
60
+ while (this.messageQueue.length > 0) {
61
+ const data = this.messageQueue.shift();
62
+ this.send(data);
63
+ }
64
+ }
65
+
66
+ mockServerSend(data: any): void {
67
+ if (this.readyState === MockWebSocket.OPEN) {
68
+ const messageData = typeof data === 'string' ? data : JSON.stringify(data);
69
+ const messageEvent = new MessageEvent('message', {
70
+ data: messageData,
71
+ });
72
+
73
+ this.onmessage?.(messageEvent);
74
+ }
75
+ }
76
+
77
+ mockServerError(error: any): void {
78
+ const errorEvent = new Event('error');
79
+
80
+ this.onerror?.(errorEvent);
81
+ }
82
+ }
83
+
84
+ class WebSocketMockServer {
85
+ private clients: Set<MockWebSocket> = new Set();
86
+ private broadcastIntervals: any[] = [];
87
+ private static instance: WebSocketMockServer;
88
+
89
+ public mockResponses = {};
90
+
91
+ public static getInstance(): WebSocketMockServer {
92
+ if (!WebSocketMockServer.instance) {
93
+ WebSocketMockServer.instance = new WebSocketMockServer();
94
+ }
95
+ return WebSocketMockServer.instance;
96
+ }
97
+
98
+ private constructor() {
99
+ FW.Log.system('🎮 WebSocket 模拟服务器已启动');
100
+ }
101
+
102
+ addClient(client: MockWebSocket): void {
103
+ this.clients.add(client);
104
+
105
+ FW.Log.system(`客户端连接,当前连接数: ${this.clients.size}`);
106
+
107
+ this.sendToClient(client, {
108
+ code: 0,
109
+ message: '连接到模拟游戏服务器成功',
110
+ serverTime: FW.Entry.timeMgr.getTime(),
111
+ });
112
+ }
113
+
114
+ removeClient(client: MockWebSocket): void {
115
+ this.clients.delete(client);
116
+ FW.Log.system(`客户端断开,当前连接数: ${this.clients.size}`);
117
+ }
118
+
119
+ handleClient(client: MockWebSocket, data: any): void {
120
+ try {
121
+ const message = typeof data === 'string' ? JSON.parse(data) : data;
122
+
123
+ const response = this.generateMockResponse(message);
124
+ this.sendToClient(client, response);
125
+ } catch (error) {
126
+ this.sendToClient(client, {
127
+ type: 'error',
128
+ message: '消息格式错误',
129
+ timestamp: new Date().toISOString(),
130
+ });
131
+ }
132
+ }
133
+
134
+ handleMessage(client: MockWebSocket, data: string | ArrayBuffer | Blob | ArrayBufferView): void {
135
+ if (typeof data === 'string') {
136
+ this.handleClient(client, data);
137
+ } else {
138
+ console.warn('二进制消息暂不支持');
139
+ }
140
+ }
141
+
142
+ private generateMockResponse(message: any): any {
143
+ return (
144
+ this.mockResponses[message.type as keyof typeof this.mockResponses] || {
145
+ type: 'unknown',
146
+ success: false,
147
+ message: { error: 'unknown message' },
148
+ }
149
+ );
150
+ }
151
+
152
+ private sendToClient(client: MockWebSocket, data: any): void {
153
+ client.mockServerSend(data);
154
+ }
155
+
156
+ public broadcast(data: any): void {
157
+ const message = typeof data === 'string' ? data : JSON.stringify(data);
158
+ this.clients.forEach((client) => {
159
+ this.sendToClient(client, message);
160
+ });
161
+ }
162
+
163
+ public stop(): void {
164
+ this.broadcastIntervals.forEach((interval) => clearInterval(interval));
165
+ this.broadcastIntervals = [];
166
+ this.clients.clear();
167
+ FW.Log.system('🛑 WebSocket 模拟服务器已停止');
168
+ }
169
+ }
170
+
171
+ export class FWSocketMock {
172
+ private isInitialized = false;
173
+
174
+ start(mockResponses: {}): void {
175
+ if (this.isInitialized) return;
176
+
177
+ WebSocketMockServer.getInstance().mockResponses = mockResponses;
178
+
179
+ const OriginalWebSocket = window.WebSocket;
180
+
181
+ (window as any).WebSocket = MockWebSocket;
182
+ (window as any).OriginalWebSocket = OriginalWebSocket;
183
+
184
+ this.isInitialized = true;
185
+ FW.Log.system('🎮 WebSocket 模拟已启动 - 所有 WebSocket 连接将被模拟');
186
+ }
187
+
188
+ stop(): void {
189
+ if (!this.isInitialized) return;
190
+
191
+ if ((window as any).OriginalWebSocket) {
192
+ window.WebSocket = (window as any).OriginalWebSocket;
193
+ }
194
+
195
+ WebSocketMockServer.getInstance().stop();
196
+ this.isInitialized = false;
197
+ FW.Log.system('🛑 WebSocket 模拟已停止 - 恢复原生 WebSocket');
198
+ }
199
+
200
+ getServer(): WebSocketMockServer {
201
+ return WebSocketMockServer.getInstance();
202
+ }
203
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "ver": "1.1.0",
3
+ "uuid": "a8d930bd-0449-4481-8ebd-e0664d7cd09f",
4
+ "importer": "typescript",
5
+ "isPlugin": false,
6
+ "loadPluginInWeb": true,
7
+ "loadPluginInNative": true,
8
+ "loadPluginInEditor": false,
9
+ "subMetas": {}
10
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "ver": "1.1.3",
3
+ "uuid": "755d7ddd-de7b-4f43-9a7a-1fbd31b2a0b9",
4
+ "importer": "folder",
5
+ "isBundle": false,
6
+ "bundleName": "",
7
+ "priority": 1,
8
+ "compressionType": {},
9
+ "optimizeHotUpdate": {},
10
+ "inlineSpriteFrames": {},
11
+ "isRemoteBundle": {},
12
+ "subMetas": {}
13
+ }
package/types/FW.d.ts CHANGED
@@ -2339,3 +2339,11 @@ declare namespace FW {
2339
2339
  onTimeout?();
2340
2340
  }
2341
2341
  }
2342
+
2343
+ declare namespace FW {
2344
+ export class SocketMock {
2345
+ static createMockData<T>(msgId: string, data: T);
2346
+ public static start(mockResponses: {}): void;
2347
+ public static stop(): void;
2348
+ }
2349
+ }