dsh-remote-hub 0.4.0 → 0.4.1
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/README.md +2 -2
- package/bin/dsh-remote.mjs +18 -1
- package/lib/bridge.js +5 -1
- package/lib/index.js +1 -1
- package/lib/supervisor.js +12 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,9 +19,9 @@ Kotlin/Compose 直连 DSH 自带的 HTTP API + WebSocket 网关。
|
|
|
19
19
|
|
|
20
20
|
## 下载手机端 App
|
|
21
21
|
|
|
22
|
-
**DSH Remote v4.21.
|
|
22
|
+
**DSH Remote v4.21.2** · Android 8.0 (API 26) 及以上 · 2.8 MB
|
|
23
23
|
|
|
24
|
-
[⬇️ 下载 APK](https://github.com/liaoguogang-hub/dsh-remote-public/releases/download/v4.21.
|
|
24
|
+
[⬇️ 下载 APK](https://github.com/liaoguogang-hub/dsh-remote-public/releases/download/v4.21.2/DSH-Remote-v4.21.2.apk) ·
|
|
25
25
|
[全部版本](https://github.com/liaoguogang-hub/dsh-remote-public/releases)
|
|
26
26
|
|
|
27
27
|
安装后应用名「DSH Remote」,包名 `com.dsh.remote.ngrok`(可与作者的 `DSH` 自用版共存)。
|
package/bin/dsh-remote.mjs
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* dsh-remote status show LAN URL, public URL, cookie and upstream port
|
|
6
6
|
* dsh-remote connect print the two lines to paste into the phone
|
|
7
7
|
* dsh-remote cookie print only the cookie
|
|
8
|
-
* dsh-remote start [--open] [--public-url=URL]
|
|
8
|
+
* dsh-remote start [--open] [--restart] [--public-url=URL] --restart 会先停掉配置不同的旧桥接
|
|
9
9
|
* dsh-remote stop ask a foreground `start` to stop (best effort, via status file)
|
|
10
10
|
* dsh-remote doctor check every prerequisite in one pass
|
|
11
11
|
* dsh-remote qr open the pairing page (QR) in the default browser
|
|
@@ -260,9 +260,26 @@ async function main() {
|
|
|
260
260
|
break
|
|
261
261
|
case 'start': {
|
|
262
262
|
const wantOpen = process.argv.includes('--open')
|
|
263
|
+
const wantRestart = process.argv.includes('--restart')
|
|
263
264
|
// --public-url=https://relay.example advertises a self-hosted relay in the QR payload.
|
|
264
265
|
const publicArg = process.argv.find((a) => a.startsWith('--public-url='))
|
|
265
266
|
const publicUrl = publicArg ? publicArg.slice('--public-url='.length) : process.env.DSH_REMOTE_PUBLIC_URL || ''
|
|
267
|
+
// A launcher that carries its own transport config must not silently adopt a bridge started
|
|
268
|
+
// with different config (that is how a public launcher ended up advertising a self-use relay).
|
|
269
|
+
if (wantRestart) {
|
|
270
|
+
const live = await bridgeHealthy(Number(process.env.DSH_REMOTE_PORT || 6300))
|
|
271
|
+
const mismatch = live && (live.relay || null) !== (publicUrl || null)
|
|
272
|
+
if (mismatch && live.pid) {
|
|
273
|
+
console.log(`已有桥接配置不同(relay=${live.relay ?? '无'}),先停止它(PID ${live.pid})再按当前配置启动`)
|
|
274
|
+
try {
|
|
275
|
+
process.kill(Number(live.pid))
|
|
276
|
+
} catch (err) {
|
|
277
|
+
console.log(`停止失败:${err.message}`)
|
|
278
|
+
}
|
|
279
|
+
await new Promise((r) => setTimeout(r, 1200))
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
266
283
|
let handle
|
|
267
284
|
try {
|
|
268
285
|
handle = await start({ publicUrl, log: (m) => console.log(m) })
|
package/lib/bridge.js
CHANGED
|
@@ -68,7 +68,7 @@ function trimSessionList(body) {
|
|
|
68
68
|
* @param {(msg: string) => void} [options.log]
|
|
69
69
|
* @returns {Promise<{close: () => Promise<void>, port: number}>}
|
|
70
70
|
*/
|
|
71
|
-
export function startBridge({ listenPort, authority, upstream, pairing = null, log = () => {} }) {
|
|
71
|
+
export function startBridge({ listenPort, authority, upstream, pairing = null, relayUrl = null, log = () => {} }) {
|
|
72
72
|
const forward = (req, res, attempt = 0) =>
|
|
73
73
|
new Promise((resolve) => {
|
|
74
74
|
upstream.resolve(attempt > 0).then((port) => {
|
|
@@ -155,6 +155,10 @@ export function startBridge({ listenPort, authority, upstream, pairing = null, l
|
|
|
155
155
|
const body = JSON.stringify({
|
|
156
156
|
ok: true,
|
|
157
157
|
service: 'dsh-remote-bridge',
|
|
158
|
+
pid: process.pid,
|
|
159
|
+
// Whether this bridge advertises a self-hosted relay; a launcher that expects none must not
|
|
160
|
+
// adopt a bridge that has one, or the public app would show the self-use relay.
|
|
161
|
+
relay: relayUrl || null,
|
|
158
162
|
// A bridge built before pairing existed has no such route; callers use this flag to decide
|
|
159
163
|
// whether an already-listening port can be adopted or must be bypassed.
|
|
160
164
|
pairing: pairing != null,
|
package/lib/index.js
CHANGED
|
@@ -16,7 +16,7 @@ import { start } from './supervisor.js'
|
|
|
16
16
|
|
|
17
17
|
export const name = 'dsh-remote-hub'
|
|
18
18
|
|
|
19
|
-
export const version = '0.4.
|
|
19
|
+
export const version = '0.4.1'
|
|
20
20
|
|
|
21
21
|
/** No host services are required: the plugin only needs Node builtins. */
|
|
22
22
|
export const inject = []
|
package/lib/supervisor.js
CHANGED
|
@@ -274,6 +274,10 @@ export async function start(config = {}) {
|
|
|
274
274
|
const lanUrlsFor = (bridgePort) =>
|
|
275
275
|
lanAddresses().map((address) => `http://${address}:${bridgePort}`)
|
|
276
276
|
|
|
277
|
+
// The self-hosted relay (if configured) and the auto tunnel are reported SEPARATELY: a self-use
|
|
278
|
+
// setup wants both (relay for 4G, ngrok as a second path), and the phone decides which to use.
|
|
279
|
+
const relayUrl = String(publicUrl || '').trim().replace(/\/+$/, '') || null
|
|
280
|
+
|
|
277
281
|
let bridgeInstance = null
|
|
278
282
|
const actualBridgePort = () => (bridgeInstance ? bridgeInstance.port : Number(port) || 6300)
|
|
279
283
|
|
|
@@ -312,6 +316,7 @@ export async function start(config = {}) {
|
|
|
312
316
|
authority,
|
|
313
317
|
upstream: discovery,
|
|
314
318
|
pairing,
|
|
319
|
+
relayUrl,
|
|
315
320
|
log,
|
|
316
321
|
})
|
|
317
322
|
} catch (err) {
|
|
@@ -337,7 +342,13 @@ export async function start(config = {}) {
|
|
|
337
342
|
authority: existing.authority ?? authority,
|
|
338
343
|
upstreamPort: existing.upstreamPort ?? null,
|
|
339
344
|
lan: { ip, url: ip ? `http://${ip}:${livePort}` : null },
|
|
340
|
-
|
|
345
|
+
// Never inherit the previous run's public address: it may describe a different transport
|
|
346
|
+
// (e.g. a self-use relay) than the launcher that is running now.
|
|
347
|
+
public: existing.relay
|
|
348
|
+
? { url: existing.relay, kind: 'relay' }
|
|
349
|
+
: { url: null, kind: 'none', note: 'served by an existing bridge' },
|
|
350
|
+
relay: existing.relay ? { url: existing.relay } : null,
|
|
351
|
+
tunnel: null,
|
|
341
352
|
cookie: prev.cookie ?? null,
|
|
342
353
|
cookieExpiresAt: prev.cookieExpiresAt ?? null,
|
|
343
354
|
pairing: { url: prev.public?.url ?? (ip ? `http://${ip}:${livePort}` : null), page: '/_dsh-remote/pair' },
|
|
@@ -405,9 +416,6 @@ export async function start(config = {}) {
|
|
|
405
416
|
},
|
|
406
417
|
})
|
|
407
418
|
|
|
408
|
-
// The self-hosted relay (if configured) and the auto tunnel are reported SEPARATELY: a self-use
|
|
409
|
-
// setup wants both (relay for 4G, ngrok as a second path), and the phone decides which to use.
|
|
410
|
-
const relayUrl = String(publicUrl || '').trim().replace(/\/+$/, '') || null
|
|
411
419
|
lastPublicUrl = relayUrl ?? tunnel.publicUrl
|
|
412
420
|
let relayReachable = null
|
|
413
421
|
if (relayUrl) {
|
package/package.json
CHANGED