dsh-bridge-gateway 0.1.3 → 0.1.4
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/CHANGELOG.md +5 -0
- package/client/client.js +20 -4
- package/client/index.js +19 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
本项目 `dsh-bridge-gateway` 是基于 [dsh-bridge](https://github.com/wenbin-wb/dsh-bridge) 的移植增强分支,在保留原版能力之外,重点新增「公网直连网关」。
|
|
4
4
|
|
|
5
|
+
## [0.1.4] - 待发布
|
|
6
|
+
|
|
7
|
+
### 修复
|
|
8
|
+
- 修复「远程访问」面板在宿主连接未建立时无限卡在「加载中」的问题:为状态拉取增加兜底超时(15s),超时后释放 in-flight 锁并给出可用的「🔄 重试」按钮,避免面板永远无法自行恢复。
|
|
9
|
+
|
|
5
10
|
## [0.1.3] - 待发布
|
|
6
11
|
|
|
7
12
|
### 修复
|
package/client/client.js
CHANGED
|
@@ -2920,18 +2920,29 @@ function BridgePanel({ rpcCall }) {
|
|
|
2920
2920
|
}, [rpcCall, adminToken]);
|
|
2921
2921
|
const loadInFlightRef = React.useRef(false);
|
|
2922
2922
|
const loadSeqRef = React.useRef(0);
|
|
2923
|
+
const LOAD_TIMEOUT_MS = 15e3;
|
|
2923
2924
|
const load = React.useCallback(async (quiet = false) => {
|
|
2924
2925
|
if (loadInFlightRef.current) return;
|
|
2925
2926
|
loadInFlightRef.current = true;
|
|
2926
2927
|
const currentSeq = ++loadSeqRef.current;
|
|
2928
|
+
const timedOut = { done: false };
|
|
2927
2929
|
try {
|
|
2928
|
-
const
|
|
2930
|
+
const result = await Promise.race([
|
|
2931
|
+
authRpcCall(BRIDGE_ENDPOINTS.getStatus, {}),
|
|
2932
|
+
new Promise((resolve) => {
|
|
2933
|
+
setTimeout(() => {
|
|
2934
|
+
timedOut.done = true;
|
|
2935
|
+
resolve(null);
|
|
2936
|
+
}, LOAD_TIMEOUT_MS);
|
|
2937
|
+
})
|
|
2938
|
+
]);
|
|
2939
|
+
if (timedOut.done) throw new Error("\u52A0\u8F7D\u8D85\u65F6\uFF08\u5BBF\u4E3B\u8FDE\u63A5\u53EF\u80FD\u5728\u5207\u6362\u6216\u672A\u5EFA\u7ACB\uFF09\u3002\u8BF7\u70B9\u51FB\u300C\u{1F504} \u91CD\u8BD5\u300D\u5237\u65B0\u3002");
|
|
2929
2940
|
if (currentSeq !== loadSeqRef.current) return;
|
|
2930
|
-
if (!
|
|
2931
|
-
setStatus(
|
|
2941
|
+
if (!result?.ok) throw new Error(result?.error?.message ?? "RPC failed");
|
|
2942
|
+
setStatus(result.value);
|
|
2932
2943
|
if (!quiet) setErr(null);
|
|
2933
2944
|
} catch (e) {
|
|
2934
|
-
if (currentSeq === loadSeqRef.current) setErr(e.message);
|
|
2945
|
+
if (currentSeq === loadSeqRef.current) setErr(e.message || "\u52A0\u8F7D\u5931\u8D25");
|
|
2935
2946
|
} finally {
|
|
2936
2947
|
loadInFlightRef.current = false;
|
|
2937
2948
|
}
|
|
@@ -3345,6 +3356,11 @@ function BridgePanel({ rpcCall }) {
|
|
|
3345
3356
|
}
|
|
3346
3357
|
},
|
|
3347
3358
|
React.createElement("span", { style: { flex: "1 1 auto" } }, err),
|
|
3359
|
+
!isInterceptionErr && React.createElement("button", {
|
|
3360
|
+
type: "button",
|
|
3361
|
+
style: { ...s.btnGhost, height: 26, fontSize: 12, padding: "0 10px", flexShrink: 0 },
|
|
3362
|
+
onClick: () => load()
|
|
3363
|
+
}, "\u{1F504} \u91CD\u8BD5"),
|
|
3348
3364
|
isInterceptionErr && React.createElement("button", {
|
|
3349
3365
|
type: "button",
|
|
3350
3366
|
style: { ...s.btnPri, background: "#dc2626", color: "#ffffff", height: 26, fontSize: 12, padding: "0 10px", flexShrink: 0 },
|
package/client/index.js
CHANGED
|
@@ -2597,18 +2597,28 @@ function BridgePanel({ rpcCall }) {
|
|
|
2597
2597
|
|
|
2598
2598
|
const loadInFlightRef = React.useRef(false);
|
|
2599
2599
|
const loadSeqRef = React.useRef(0);
|
|
2600
|
+
// 兜底超时:RPC 若一直不返回(连接打不开/宿主未响应),强制结束「加载中」,
|
|
2601
|
+
// 释放 in-flight 锁并提示重试,避免面板无限卡在加载态
|
|
2602
|
+
const LOAD_TIMEOUT_MS = 15000;
|
|
2600
2603
|
const load = React.useCallback(async (quiet = false) => {
|
|
2601
2604
|
if (loadInFlightRef.current) return;
|
|
2602
2605
|
loadInFlightRef.current = true;
|
|
2603
2606
|
const currentSeq = ++loadSeqRef.current;
|
|
2607
|
+
const timedOut = { done: false };
|
|
2604
2608
|
try {
|
|
2605
|
-
const
|
|
2609
|
+
const result = await Promise.race([
|
|
2610
|
+
authRpcCall(BRIDGE_ENDPOINTS.getStatus, {}),
|
|
2611
|
+
new Promise((resolve) => {
|
|
2612
|
+
setTimeout(() => { timedOut.done = true; resolve(null); }, LOAD_TIMEOUT_MS);
|
|
2613
|
+
}),
|
|
2614
|
+
]);
|
|
2615
|
+
if (timedOut.done) throw new Error('加载超时(宿主连接可能在切换或未建立)。请点击「🔄 重试」刷新。');
|
|
2606
2616
|
if (currentSeq !== loadSeqRef.current) return;
|
|
2607
|
-
if (!
|
|
2608
|
-
setStatus(
|
|
2617
|
+
if (!result?.ok) throw new Error(result?.error?.message ?? 'RPC failed');
|
|
2618
|
+
setStatus(result.value);
|
|
2609
2619
|
if (!quiet) setErr(null);
|
|
2610
2620
|
} catch (e) {
|
|
2611
|
-
if (currentSeq === loadSeqRef.current) setErr(e.message);
|
|
2621
|
+
if (currentSeq === loadSeqRef.current) setErr(e.message || '加载失败');
|
|
2612
2622
|
} finally {
|
|
2613
2623
|
loadInFlightRef.current = false;
|
|
2614
2624
|
}
|
|
@@ -2977,6 +2987,11 @@ function BridgePanel({ rpcCall }) {
|
|
|
2977
2987
|
},
|
|
2978
2988
|
},
|
|
2979
2989
|
React.createElement('span', { style: { flex: '1 1 auto' } }, err),
|
|
2990
|
+
!isInterceptionErr && React.createElement('button', {
|
|
2991
|
+
type: 'button',
|
|
2992
|
+
style: { ...s.btnGhost, height: 26, fontSize: 12, padding: '0 10px', flexShrink: 0 },
|
|
2993
|
+
onClick: () => load(),
|
|
2994
|
+
}, '🔄 重试'),
|
|
2980
2995
|
isInterceptionErr && React.createElement('button', {
|
|
2981
2996
|
type: 'button',
|
|
2982
2997
|
style: { ...s.btnPri, background: '#dc2626', color: '#ffffff', height: 26, fontSize: 12, padding: '0 10px', flexShrink: 0 },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-bridge-gateway",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "以 dsh-bridge 为根基、融合 remote-gateway 能力的 DSH 远程访问网关:局域网 / Cloudflare 隧道 / 自建隧道之外,新增「公网直连网关」(0.0.0.0 监听 + 自带 HTTPS 自签证书 + 强制登录门禁),解决移动端外网直连操控电脑。",
|
|
5
5
|
"releaseNotes": "【dsh-bridge-gateway】以 dsh-bridge 为根基、融合 remote-gateway 能力的 DSH 远程访问网关\n• ➕ 公网访问区:隧道 / 直连网关 二选一,网关全部配置项可在界面配置\n• ➕ 直连网关:0.0.0.0:<端口> 自带 HTTPS(自签证书) + 强制 public_only 门禁,复用 AuthManager,链路打通到 DSH loopback\n• 📱 修复移动端选择模型时界面溢出屏幕的问题\n• 默认不启用,安装后原有局域网/隧道/IM 行为完全不变",
|
|
6
6
|
"type": "module",
|