I have an instance of a websocket API implemented as a singleton in the main process of my electron app and I want to display the active connections in my renderer. Here's how I'm trying to set it up:
export interface IUserData {
name: string;
socket_id: string;
}
export class MyAPI {
private static instance: MyAPI;
private connections: Map<string, IUserData>;
private sio: sockio.Server;
private connectCallback?: () => void;
private constructor() {
//...
this.sio.on("connection", this.connectHandler);
//...
}
public static getInstance(): MyAPI {{/*...*/}
// This is called
private connectHandler(socket: sockio.Socket) {
if (!MyAPI.instance) return;
const name = socket.handshake.auth.name;
this.connections.set(name, { name: name, socket_id: socket.id });
socket.on("disconnect", /*...*/);
if (this.connectCallback) this.connectCallback();
}
public getConnections(): IUserData[] {
if (!this.connections) return [];
const output: IUserData[] = [];
this.connections.forEach((val) => output.push(val));
return output;
}
public setConnectCallback(callback: () => void) {
this.connectCallback = callback;
}
}
const createWindow = () => {
// init API
const myAPI= MyAPI.getInstance();
// Create the browser window.
const mainWindow = new BrowserWindow({
/*...*/
webPreferences: {
preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY,
},
});
mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY);
mainWindow.webContents.openDevTools({ mode: "right" });
myAPI.setConnectCallback(() => {
const content = myAPI.getConnections();
mainWindow.webContents.send("set-user-list", content);
});
};
app.whenReady().then(() => {
installExtension([REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS])
.then((name) => console.log(`Added Extension: ${name}`))
.catch((err) => console.log(`An error occurred: ${err}`));
createWindow();
/*...*/
});
/*...*/
contextBridge.exposeInMainWorld("sysAPI", {
onUserListChange: (callback: (content: IUserData[]) => void) =>
ipcRenderer.on("set-user-list", (_event, value: IUserData[]) => callback(value)),
});
I think my IPC is working correctly. The issue happens when I call myAPI.setConnectCallback(). When the process gets into the setConnectCallback method in the debugger, the function I pass shows up as undefined and I cannot fathom why. As a result, the connectHandler method does not call this.connectCallback, as it's undefined. I also tried to define the callback as a named function, but it did not change anything.
I'm using webpack.
Thanks in advance!