MCPcopy Create free account
hub / github.com/NiREvil/vless / makeReadableWebSocketStream

Function makeReadableWebSocketStream

edge/LoadBalance.js:250–305  ·  view source on GitHub ↗

* * @param {import("@cloudflare/workers-types").WebSocket} webSocketServer * @param {string} earlyDataHeader for ws 0rtt * @param {(info: string)=> void} log for ws 0rtt

(webSocketServer, earlyDataHeader, log)

Source from the content-addressed store, hash-verified

248 * @param {(info: string)=> void} log for ws 0rtt
249 */
250function makeReadableWebSocketStream(webSocketServer, earlyDataHeader, log) {
251 let readableStreamCancel = false;
252 const stream = new ReadableStream({
253 start(controller) {
254 webSocketServer.addEventListener("message", (event) => {
255 if (readableStreamCancel) {
256 return;
257 }
258 const message = event.data;
259 controller.enqueue(message);
260 });
261
262 // The event means that the client closed the client -> server stream.
263 // However, the server -> client stream is still open until you call close() on the server side.
264 // The WebSocket protocol says that a separate close message must be sent in each direction to fully close the socket.
265 webSocketServer.addEventListener("close", () => {
266 // client send close, need close server
267 // if stream is cancel, skip controller.close
268 safeCloseWebSocket(webSocketServer);
269 if (readableStreamCancel) {
270 return;
271 }
272 controller.close();
273 });
274 webSocketServer.addEventListener("error", (err) => {
275 log("webSocketServer has error");
276 controller.error(err);
277 });
278 // for ws 0rtt
279 const { earlyData, error } = base64ToArrayBuffer(earlyDataHeader);
280 if (error) {
281 controller.error(error);
282 } else if (earlyData) {
283 controller.enqueue(earlyData);
284 }
285 },
286
287 pull(controller) {
288 // if ws can stop read if stream is full, we can implement backpressure
289 // https://streams.spec.whatwg.org/#example-rs-push-backpressure
290 },
291 cancel(reason) {
292 // 1. pipe WritableStream has error, this cancel will called, so ws handle server close into here
293 // 2. if readableStream is cancel, all controller.close/enqueue need skip,
294 // 3. but from testing controller.error still work even if readableStream is cancel
295 if (readableStreamCancel) {
296 return;
297 }
298 log(`ReadableStream was canceled, due to ${reason}`);
299 readableStreamCancel = true;
300 safeCloseWebSocket(webSocketServer);
301 },
302 });
303
304 return stream;
305}
306
307// https://xtls.github.io/development/protocols/vless.html

Callers 1

vlessOverWSHandlerFunction · 0.70

Calls

no outgoing calls

Tested by

no test coverage detected