typescript - Issue passing function as argument to a singleton class in electron's main process - Stack Overflow

admin2025-05-02  0

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:

MyAPI.ts

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;
  }
}

main.ts

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();

  /*...*/
});

/*...*/

preload.ts

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!

转载请注明原文地址:http://anycun.com/QandA/1746118173a91919.html