@lzpenguin/server 1.0.1 → 1.0.2
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/index.js +75 -18
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,4 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
// 检测运行环境,浏览器使用原生 WebSocket,Node.js 使用 ws 库
|
|
2
|
+
let WebSocketImpl;
|
|
3
|
+
let isBrowser = false;
|
|
4
|
+
|
|
5
|
+
if (typeof window !== 'undefined' && window.WebSocket) {
|
|
6
|
+
// 浏览器环境
|
|
7
|
+
WebSocketImpl = window.WebSocket;
|
|
8
|
+
isBrowser = true;
|
|
9
|
+
} else {
|
|
10
|
+
// Node.js 环境 - 使用动态导入
|
|
11
|
+
try {
|
|
12
|
+
// 使用 require 或 import,根据环境选择
|
|
13
|
+
if (typeof require !== 'undefined') {
|
|
14
|
+
// CommonJS 环境
|
|
15
|
+
WebSocketImpl = require('ws');
|
|
16
|
+
} else {
|
|
17
|
+
// ES Module 环境 - 在运行时动态导入
|
|
18
|
+
// 注意:这需要在异步上下文中使用
|
|
19
|
+
WebSocketImpl = null; // 将在 connect 方法中动态导入
|
|
20
|
+
}
|
|
21
|
+
} catch (e) {
|
|
22
|
+
// 如果无法导入 ws,尝试使用全局 WebSocket(某些打包工具可能会提供)
|
|
23
|
+
if (typeof WebSocket !== 'undefined') {
|
|
24
|
+
WebSocketImpl = WebSocket;
|
|
25
|
+
} else {
|
|
26
|
+
throw new Error('WebSocket is not available. In Node.js, please install "ws" package.');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
2
30
|
|
|
3
31
|
/**
|
|
4
32
|
* RiffleServer - 游戏服务器 WebSocket 客户端
|
|
@@ -79,29 +107,43 @@ export class RiffleServer {
|
|
|
79
107
|
// 当前服务器数据缓存
|
|
80
108
|
this.currentData = null;
|
|
81
109
|
|
|
82
|
-
//
|
|
83
|
-
this.connect()
|
|
110
|
+
// 连接状态(异步调用,不阻塞构造函数)
|
|
111
|
+
this.connect().catch(err => {
|
|
112
|
+
console.error('[RiffleServer] Initial connection failed:', err);
|
|
113
|
+
});
|
|
84
114
|
}
|
|
85
115
|
|
|
86
116
|
/**
|
|
87
117
|
* 连接到 WebSocket 服务器
|
|
88
118
|
* @private
|
|
89
119
|
*/
|
|
90
|
-
connect() {
|
|
91
|
-
if (this.isConnecting || (this.isConnected && this.ws?.readyState ===
|
|
120
|
+
async connect() {
|
|
121
|
+
if (this.isConnecting || (this.isConnected && this.ws?.readyState === (WebSocketImpl?.OPEN ?? 1))) {
|
|
92
122
|
return;
|
|
93
123
|
}
|
|
94
124
|
|
|
95
125
|
this.isConnecting = true;
|
|
96
126
|
|
|
127
|
+
// 如果在 Node.js 环境且 WebSocketImpl 未初始化,动态导入
|
|
128
|
+
if (!isBrowser && !WebSocketImpl) {
|
|
129
|
+
try {
|
|
130
|
+
const wsModule = await import('ws');
|
|
131
|
+
WebSocketImpl = wsModule.default;
|
|
132
|
+
} catch (e) {
|
|
133
|
+
this.isConnecting = false;
|
|
134
|
+
console.error('[RiffleServer] Failed to import ws module:', e);
|
|
135
|
+
throw new Error('WebSocket is not available. In Node.js, please install "ws" package.');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
97
139
|
// 构建 WebSocket URL(包含 post_id 和 token)
|
|
98
140
|
let wsUrl = `${this.url}?post_id=${this.postId}&token=${this.token}`;
|
|
99
141
|
|
|
100
|
-
|
|
101
142
|
try {
|
|
102
|
-
this.ws = new
|
|
143
|
+
this.ws = new WebSocketImpl(wsUrl);
|
|
103
144
|
|
|
104
|
-
|
|
145
|
+
// 统一事件处理:浏览器用 addEventListener,Node.js 用 .on()
|
|
146
|
+
const handleOpen = () => {
|
|
105
147
|
this.isConnected = true;
|
|
106
148
|
this.isConnecting = false;
|
|
107
149
|
this.isInitialized = false; // 连接后重置初始化状态
|
|
@@ -113,11 +155,13 @@ export class RiffleServer {
|
|
|
113
155
|
this.pendingInit = null;
|
|
114
156
|
this._doInit(initData);
|
|
115
157
|
}
|
|
116
|
-
}
|
|
158
|
+
};
|
|
117
159
|
|
|
118
|
-
|
|
160
|
+
const handleMessage = (event) => {
|
|
119
161
|
try {
|
|
120
|
-
|
|
162
|
+
// 浏览器: event.data, Node.js: event (Buffer 或 string)
|
|
163
|
+
const data = event.data || event;
|
|
164
|
+
const message = JSON.parse(typeof data === 'string' ? data : data.toString());
|
|
121
165
|
|
|
122
166
|
// 检查是否是错误消息
|
|
123
167
|
if (message.error) {
|
|
@@ -140,13 +184,13 @@ export class RiffleServer {
|
|
|
140
184
|
} catch (error) {
|
|
141
185
|
console.error('[RiffleServer] Failed to parse message:', error);
|
|
142
186
|
}
|
|
143
|
-
}
|
|
187
|
+
};
|
|
144
188
|
|
|
145
|
-
|
|
189
|
+
const handleError = (error) => {
|
|
146
190
|
console.error('[RiffleServer] WebSocket error:', error);
|
|
147
|
-
}
|
|
191
|
+
};
|
|
148
192
|
|
|
149
|
-
|
|
193
|
+
const handleClose = () => {
|
|
150
194
|
this.isConnected = false;
|
|
151
195
|
this.isConnecting = false;
|
|
152
196
|
this.isInitialized = false; // 断开连接后重置初始化状态
|
|
@@ -159,7 +203,20 @@ export class RiffleServer {
|
|
|
159
203
|
this.connect();
|
|
160
204
|
}, this.reconnectInterval);
|
|
161
205
|
}
|
|
162
|
-
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// 根据环境使用不同的事件绑定方式
|
|
209
|
+
if (isBrowser) {
|
|
210
|
+
this.ws.addEventListener('open', handleOpen);
|
|
211
|
+
this.ws.addEventListener('message', handleMessage);
|
|
212
|
+
this.ws.addEventListener('error', handleError);
|
|
213
|
+
this.ws.addEventListener('close', handleClose);
|
|
214
|
+
} else {
|
|
215
|
+
this.ws.on('open', handleOpen);
|
|
216
|
+
this.ws.on('message', handleMessage);
|
|
217
|
+
this.ws.on('error', handleError);
|
|
218
|
+
this.ws.on('close', handleClose);
|
|
219
|
+
}
|
|
163
220
|
} catch (error) {
|
|
164
221
|
this.isConnecting = false;
|
|
165
222
|
console.error('[RiffleServer] Connection error:', error);
|
|
@@ -189,7 +246,7 @@ export class RiffleServer {
|
|
|
189
246
|
* @param {Object} updateData - 更新数据
|
|
190
247
|
*/
|
|
191
248
|
sendUpdate(updateData) {
|
|
192
|
-
if (!this.isConnected || this.ws?.readyState !==
|
|
249
|
+
if (!this.isConnected || this.ws?.readyState !== WebSocketImpl.OPEN) {
|
|
193
250
|
console.warn('[RiffleServer] Not connected, cannot send update');
|
|
194
251
|
return;
|
|
195
252
|
}
|
|
@@ -231,7 +288,7 @@ export class RiffleServer {
|
|
|
231
288
|
}
|
|
232
289
|
|
|
233
290
|
// 如果还未连接,保存 init 请求,连接建立后自动执行
|
|
234
|
-
if (!this.isConnected || this.ws?.readyState !==
|
|
291
|
+
if (!this.isConnected || this.ws?.readyState !== WebSocketImpl.OPEN) {
|
|
235
292
|
console.log('[RiffleServer] Not connected yet, will init after connection');
|
|
236
293
|
this.pendingInit = initData;
|
|
237
294
|
return;
|