@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.
package/FrameworkInitialize.ts
CHANGED
|
@@ -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,10 +1,9 @@
|
|
|
1
|
-
import { FWSystemConfig } from
|
|
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
|
|
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
|
-
|
|
113
|
-
this.
|
|
114
|
-
|
|
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(
|
|
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.
|
|
211
|
-
this.
|
|
212
|
-
this.
|
|
213
|
-
this.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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(
|
|
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(
|
|
287
|
+
FW.Log.debug('on close!');
|
|
301
288
|
this.socketHandle?.onClose?.();
|
|
302
289
|
FW.Entry.timeMgr.scheduleOnce(
|
|
303
290
|
() => {
|
|
304
|
-
if (
|
|
305
|
-
|
|
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
|
|
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,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
|
+
}
|