(private options: WebSocketStreamOptions<Req, Res>)
| 33 | |
| 34 | constructor(private options: WebSocketStreamOptions<Req, Res>) { |
| 35 | const baseUrl = serverConnectUrl(options.config.url).replace(/^http/, "ws"); |
| 36 | let socket: WebSocket; |
| 37 | try { |
| 38 | socket = new WebSocket(`${baseUrl}/${options.service}/${options.method}`, [ |
| 39 | "grpc-websockets", |
| 40 | ]); |
| 41 | } catch (error) { |
| 42 | queueMicrotask(() => this.end(null, String(error))); |
| 43 | return; |
| 44 | } |
| 45 | this.socket = socket; |
| 46 | socket.binaryType = "arraybuffer"; |
| 47 | socket.onopen = () => { |
| 48 | let headers = `content-type: application/grpc-web+proto\r\nx-grpc-web: 1\r\naccept-language: ${options.language}\r\n`; |
| 49 | if (options.config.secret) { |
| 50 | headers += `authorization: Bearer ${options.config.secret}\r\n`; |
| 51 | } |
| 52 | socket.send(new TextEncoder().encode(headers)); |
| 53 | this.opened = true; |
| 54 | for (const pending of this.pendingSends) { |
| 55 | socket.send(pending); |
| 56 | } |
| 57 | this.pendingSends = []; |
| 58 | }; |
| 59 | socket.onmessage = (event) => { |
| 60 | this.receive(new Uint8Array(event.data as ArrayBuffer)); |
| 61 | }; |
| 62 | socket.onerror = () => { |
| 63 | this.end(null, "websocket connection failed"); |
| 64 | }; |
| 65 | socket.onclose = (event) => { |
| 66 | if (this.status) { |
| 67 | this.end(this.status); |
| 68 | } else { |
| 69 | this.end(null, event.reason || "websocket closed unexpectedly"); |
nothing calls this directly
no test coverage detected