websockets / ws

Simple to use, blazing fast and thoroughly tested WebSocket client and server for Node.js
MIT License
21.34k stars 2.3k forks source link

Error creating WebSocket: TypeError: HQ.WebSocket is not a constructor (Typescript) #2189

Closed 0Akise closed 6 months ago

0Akise commented 6 months ago

Is there an existing issue for this?

Description

I'm not sure if this error is from ws package, if not, I'm sorry.

I have setup my project via [https://github.com/tgrassl/solid-vite-electron/]

and I have following codes:

// on rendering side
async function startEngine() {
    setEngineStarted(true);
    window.electronAPI.send('start-audio-stream');

    try {
        const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
        mediaRecorder = new MediaRecorder(stream);

        mediaRecorder.ondataavailable = async (event) => {
            const arrayBuffer = await event.data.arrayBuffer();

            window.electronAPI.send('send-audio-data', arrayBuffer);
        };

        mediaRecorder.start(100);
    } catch (error) {
        console.error('Error accessing audio devices:', error);
    }
}
// on main
import { app, BrowserWindow, shell, ipcMain, dialog } from "electron";
import { WebSocket } from "ws";

// ... 

ipcMain.on('start-audio-stream', () => {
    try {
        audioSocket = new WebSocket('wss://some_url/ws');

        console.log("Websocket: ", audioSocket);

        audioSocket.onopen = () => {
            console.log('WebSocket connection opened.');
        };

        audioSocket.onmessage = (message) => {
            console.log('Received from server:', message);
        };

        audioSocket.onerror = (error) => {
            console.error('WebSocket error:', error);
        };
    } catch (error) {
        console.error('Error creating WebSocket:', error);
    }
});
// on preload
contextBridge.exposeInMainWorld('electronAPI', {
    send: (channel: string, data?: any) => ipcRenderer.send(channel, data),
    receive: (channel: string, func: (...args: any[]) => void) => ipcRenderer.on(channel, (_, ...args) => func(...args)),
    invoke: (channel: string, ...args: any[]) => ipcRenderer.invoke(channel, ...args),
});

and every time, the function startEngine() is invoked, following error occurs:

Error creating WebSocket: TypeError: HQ.WebSocket is not a constructor
    at IpcMainImpl.<anonymous> (...\dist-electron\main.js:49:111922)
    at IpcMainImpl.emit (node:events:513:28)
    at EventEmitter.<anonymous> (node:electron/js2c/browser_init:2:81099)
    at EventEmitter.emit (node:events:513:28)

is this because I'm using websocket inside IPC? I'm not sure what is going on. I double checked that WebSocket url is correct. and surprisingly I cannot find any search result on the internet about "Error Creating WebSocket".

ws version

8.16.0

Node.js Version

v18.17.1

System

System: OS: Windows 10 10.0.19045 CPU: (32) x64 AMD Ryzen 9 3950X 16-Core Processor Memory: 43.75 GB / 63.91 GB

Expected result

error should not appear and websocket creates.

Actual result

following error:

Error creating WebSocket: TypeError: HQ.WebSocket is not a constructor
    at IpcMainImpl.<anonymous> (D:\Projects\pygma-client\dist-electron\main.js:49:111922)
    at IpcMainImpl.emit (node:events:513:28)
    at EventEmitter.<anonymous> (node:electron/js2c/browser_init:2:81099)
    at EventEmitter.emit (node:events:513:28)

Attachments

No response

0Akise commented 6 months ago

seems like HQ is just a automatically generated symbol for Javascript...

HQ=function(){throw new Error("ws does not work in the browser. Browser clients must use the native WebSocket object")};

what is native WebSocket???

0Akise commented 6 months ago

two things I found:

1. ws does not work in the browser. Browser clients must use the native WebSocket object
2. Electron does not have WebSocket, WebSocket is a Web API.

but that being said, I should be able to use ws package in main. why am I having this error?

lpinca commented 6 months ago

why am I having this error?

Probably because you are bundling for the browser.

0Akise commented 6 months ago

so as I understand, in the template I used, I think vite is bundling main file as browser for some reason.

I believe this is not from ws package, thus closing ticket.

lpinca commented 6 months ago

It is from ws, see https://github.com/websockets/ws/blob/d343a0cf7bba29a4e14217cb010446bec8fdf444/browser.js#L1-L8 but it happens when ws is bundled for the browser, see https://github.com/websockets/ws/blob/d343a0cf7bba29a4e14217cb010446bec8fdf444/package.json#L24