Skip to content

Commit f90a19d

Browse files
committed
refactor: simplify WebSocket connection handling and remove unused dynamic proxy plugin
1 parent 5f21822 commit f90a19d

2 files changed

Lines changed: 86 additions & 110 deletions

File tree

src/store/websocketMiddleware.ts

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,48 +18,27 @@ export const websocketMiddleware: Middleware = (store) => {
1818
if (type === WS_CONNECT) {
1919
const { url } = (action as WsConnectAction).payload;
2020

21+
console.log("[ws] Connecting to", url);
22+
2123
// Close any existing connection before opening a new one
2224
if (socket) {
2325
socket.close();
2426
}
2527

26-
const initSocket = (effectiveUrl: string) => {
27-
socket = new WebSocket(effectiveUrl);
28-
socket.onopen = () => store.dispatch(connected());
29-
socket.onclose = () => { store.dispatch(disconnected()); socket = null; };
30-
socket.onerror = (err) => console.error('WebSocket error', err);
31-
socket.onmessage = (event: MessageEvent<string>) => {
32-
try {
33-
store.dispatch(messageReceived(JSON.parse(event.data)));
34-
} catch (e) {
35-
console.error('Failed to parse WebSocket message', e);
36-
}
37-
};
28+
socket = new WebSocket(url);
29+
socket.onopen = () => store.dispatch(connected());
30+
socket.onclose = () => {
31+
store.dispatch(disconnected());
32+
socket = null;
33+
};
34+
socket.onerror = (err) => console.error("WebSocket error", err);
35+
socket.onmessage = (event: MessageEvent<string>) => {
36+
try {
37+
store.dispatch(messageReceived(JSON.parse(event.data)));
38+
} catch (e) {
39+
console.error("Failed to parse WebSocket message", e);
40+
}
3841
};
39-
40-
if (import.meta.env.DEV) {
41-
// In dev: register the dynamic port with Vite's proxy plugin so it can
42-
// tunnel the connection, then connect via localhost (no cert issues).
43-
fetch('/debug/ws-register', {
44-
method: 'POST',
45-
headers: { 'Content-Type': 'application/json' },
46-
body: JSON.stringify({ url }),
47-
})
48-
.then(() => {
49-
const parsed = new URL(url);
50-
const proto = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
51-
initSocket(`${proto}//${window.location.host}${parsed.pathname}${parsed.search}`);
52-
})
53-
.catch((err) => {
54-
console.warn('[ws] Registration failed, connecting directly:', err);
55-
initSocket(url);
56-
});
57-
} else {
58-
// In production the app is served by the device itself, so the browser
59-
// already trusts the device cert (TLS cert validation is per-hostname,
60-
// not per-port) and can connect to the high-numbered port directly.
61-
initSocket(url);
62-
}
6342

6443
return;
6544
}

vite.config.ts

Lines changed: 71 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import react from '@vitejs/plugin-react';
2-
import type { IncomingMessage } from 'node:http';
3-
import net from 'node:net';
4-
import tls from 'node:tls';
5-
import { defineConfig, loadEnv, Plugin } from 'vite';
2+
import { defineConfig, loadEnv } from 'vite';
63
import svgr from 'vite-plugin-svgr';
74

85
/**
@@ -18,82 +15,82 @@ import svgr from 'vite-plugin-svgr';
1815
* 3. This plugin intercepts the WebSocket upgrade, opens a TLS tunnel to
1916
* the registered target, and splices the two sockets together.
2017
*/
21-
function dynamicWsProxyPlugin(): Plugin {
22-
let registeredTarget: URL | null = null;
18+
// function dynamicWsProxyPlugin(): Plugin {
19+
// let registeredTarget: URL | null = null;
2320

24-
return {
25-
name: 'dynamic-ws-proxy',
26-
configureServer(server) {
27-
// ── Registration endpoint ─────────────────────────────────────────────
28-
server.middlewares.use('/debug/ws-register', (req, res) => {
29-
if (req.method !== 'POST') {
30-
res.statusCode = 405;
31-
res.end();
32-
return;
33-
}
34-
let body = '';
35-
req.on('data', (chunk: Buffer) => (body += chunk.toString()));
36-
req.on('end', () => {
37-
try {
38-
const { url } = JSON.parse(body) as { url: string };
39-
registeredTarget = new URL(url);
40-
res.statusCode = 200;
41-
res.setHeader('Content-Type', 'application/json');
42-
res.end(JSON.stringify({ ok: true }));
43-
} catch {
44-
res.statusCode = 400;
45-
res.end(JSON.stringify({ error: 'Invalid request body' }));
46-
}
47-
});
48-
});
21+
// return {
22+
// name: 'dynamic-ws-proxy',
23+
// configureServer(server) {
24+
// // ── Registration endpoint ─────────────────────────────────────────────
25+
// server.middlewares.use('/debug/ws-register', (req, res) => {
26+
// if (req.method !== 'POST') {
27+
// res.statusCode = 405;
28+
// res.end();
29+
// return;
30+
// }
31+
// let body = '';
32+
// req.on('data', (chunk: Buffer) => (body += chunk.toString()));
33+
// req.on('end', () => {
34+
// try {
35+
// const { url } = JSON.parse(body) as { url: string };
36+
// registeredTarget = new URL(url);
37+
// res.statusCode = 200;
38+
// res.setHeader('Content-Type', 'application/json');
39+
// res.end(JSON.stringify({ ok: true }));
40+
// } catch {
41+
// res.statusCode = 400;
42+
// res.end(JSON.stringify({ error: 'Invalid request body' }));
43+
// }
44+
// });
45+
// });
4946

50-
// ── Dynamic WebSocket tunnel ──────────────────────────────────────────
51-
server.httpServer?.prependListener(
52-
'upgrade',
53-
(req: IncomingMessage, socket: any, head: Buffer) => {
54-
if (!req.url?.startsWith('/debug/join') || !registeredTarget) return;
47+
// // ── Dynamic WebSocket tunnel ──────────────────────────────────────────
48+
// server.httpServer?.prependListener(
49+
// 'upgrade',
50+
// (req: IncomingMessage, socket: any, head: Buffer) => {
51+
// if (!req.url?.startsWith('/debug/join') || !registeredTarget) return;
5552

56-
const target = registeredTarget;
57-
const useSecure =
58-
target.protocol === 'wss:' || target.protocol === 'https:';
59-
const port = target.port
60-
? parseInt(target.port, 10)
61-
: useSecure ? 443 : 80;
53+
// const target = registeredTarget;
54+
// const useSecure =
55+
// target.protocol === 'wss:' || target.protocol === 'https:';
56+
// const port = target.port
57+
// ? parseInt(target.port, 10)
58+
// : useSecure ? 443 : 80;
6259

63-
const upstream: net.Socket = useSecure
64-
? tls.connect({ host: target.hostname, port, rejectUnauthorized: false })
65-
: net.createConnection({ host: target.hostname, port });
60+
// const upstream: net.Socket = useSecure
61+
// ? tls.connect({ host: target.hostname, port, rejectUnauthorized: false })
62+
// : net.createConnection({ host: target.hostname, port });
6663

67-
upstream.once(useSecure ? 'secureConnect' : 'connect', () => {
68-
// Re-emit the full HTTP Upgrade request to the upstream server
69-
const headerLines = [
70-
`GET ${req.url} HTTP/1.1`,
71-
`Host: ${target.host}`,
72-
...Object.entries(req.headers)
73-
.filter(([k]) => k !== 'host')
74-
.map(([k, v]) => `${k}: ${Array.isArray(v) ? v.join(', ') : (v ?? '')}` ),
75-
'',
76-
'',
77-
];
78-
upstream.write(headerLines.join('\r\n'));
79-
if (head?.length) upstream.write(head);
64+
// upstream.once(useSecure ? 'secureConnect' : 'connect', () => {
65+
// // Re-emit the full HTTP Upgrade request to the upstream server
66+
// const headerLines = [
67+
// `GET ${req.url} HTTP/1.1`,
68+
// `Host: ${target.host}`,
69+
// ...Object.entries(req.headers)
70+
// .filter(([k]) => k !== 'host')
71+
// .map(([k, v]) => `${k}: ${Array.isArray(v) ? v.join(', ') : (v ?? '')}` ),
72+
// '',
73+
// '',
74+
// ];
75+
// upstream.write(headerLines.join('\r\n'));
76+
// if (head?.length) upstream.write(head);
8077

81-
socket.pipe(upstream);
82-
upstream.pipe(socket);
83-
});
78+
// socket.pipe(upstream);
79+
// upstream.pipe(socket);
80+
// });
8481

85-
upstream.on('error', (err: Error) => {
86-
console.error('[dynamic-ws-proxy] upstream error:', err.message);
87-
socket.destroy();
88-
});
89-
socket.on('error', () => upstream.destroy());
90-
socket.on('close', () => upstream.destroy());
91-
upstream.on('close', () => socket.destroy());
92-
},
93-
);
94-
},
95-
};
96-
}
82+
// upstream.on('error', (err: Error) => {
83+
// console.error('[dynamic-ws-proxy] upstream error:', err.message);
84+
// socket.destroy();
85+
// });
86+
// socket.on('error', () => upstream.destroy());
87+
// socket.on('close', () => upstream.destroy());
88+
// upstream.on('close', () => socket.destroy());
89+
// },
90+
// );
91+
// },
92+
// };
93+
// }
9794

9895
export default defineConfig(({ mode }) => {
9996
const env = loadEnv(mode, process.cwd(), '');
@@ -105,7 +102,7 @@ export default defineConfig(({ mode }) => {
105102

106103
return {
107104
base: '/debug/',
108-
plugins: [react(), svgr({ include: '**/*.svg', svgrOptions: { exportType: 'named' } }), dynamicWsProxyPlugin()],
105+
plugins: [react(), svgr({ include: '**/*.svg', svgrOptions: { exportType: 'named' } })],
109106
server: {
110107
proxy: programHost
111108
? {

0 commit comments

Comments
 (0)