Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalid value for transfer with ipcRenderer.postMessage in Electron

I'm getting this error message : Invalid value for transfer when trying to use, for the very first time, the message-ports-reply-streams.

In preload.js I defined this api:

 contextBridge.exposeInMainWorld(
  "api", {
      electronIpcPostMessage: (channel: string, message: any, transfer?: MessagePort[]) => {
        ipcRenderer.postMessage(channel, message, transfer)
      },
  }
)
declare global {
  interface Window {
    api: {
      electronIpcPostMessage: (channel: string, message: any, transfer?: MessagePort[]) => void;
  }
}

And , following the example found here: https://www.electronjs.org/docs/latest/tutorial/message-ports#reply-streams , in the renderer React component I defined the streaming request as follows:

 const Layers = () => {


  const componentIsMounted = React.useRef(true)

  React.useEffect(() => {

    const cb = (event, args) => {
      try {
        if (componentIsMounted.current) {
          console.log("react-leaflet-layers-args: ", args)
        }
      } catch (err) {
        console.log("err: ", err)
      }
    }
    const makeStreamingRequest = (element, cb) => {
      // MessageChannels are lightweight--it's cheap to create a new one for each request.
      const { port1, port2 } = new MessageChannel()

      // We send one end of the port to the main process ...
      window.api.electronIpcPostMessage(
        'give-me-a-stream',
        { element, count: 10 },
        [port2]
      )

      // ... and we hang on to the other end.
      // The main process will send messages to its end of the port,
      // and close it when it's finished.
      port1.onmessage = (event) => {
        cb(event.data)
      }
      port1.onclose = () => {
        console.log('stream ended')
      }
    }

    makeStreamingRequest(42, (data) => {
      console.log('got response data:', event.data)
    })
    // We will see "got response data: 42" 10 times.
    return () => { // clean-up function
      componentIsMounted.current = false
      window.api.electronIpcRemoveListener(
        "give-me-a-stream",
        cb,
      )
    }
  }, [])

As said, when running Electron-React app the error message I get when accessing the page rendered by that component, is : Invalid value for transfer .

From this StackOverflow question : Invalid value for transfer while using ipcRenderer.postMessage of electron, it seems that I'm not the only one stumbling on this type of error, but I didn't find any solutions yet.

What am I doing wrongly or missing? How to solve the problem?

My objective is to send, better in a streaming fashion, a very big geojson file from the main process to the renderer process. That's why I thought to try to use ipcRenderer.postMessage. By the way, any other working solutions that accomplish this goal, are welcomed.

Other info:

electron: v. 16
node: v. 16.13.0
O.S: Ubuntu 20.04

Looking forward to hints and help

like image 849
Raphael10 Avatar asked Sep 15 '25 21:09

Raphael10


1 Answers

I also encountered the same problem. In https://www.electronjs.org/docs/latest/api/context-bridge, it is mentioned that the types of parameters, errors and return values in functions bound with contextBridge are restricted, and MessagePort is one of the types that cannot be transported, so it doesn't recognize the MessagePort you passed in and throw this error.

If you want to use MessageChannel for communication, you can provide some proxy functions through contextBridge in preload.js, call these functions in renderer.js and pass in copyable parameters.

Hope my answer helps you.

like image 119
Blossom4696 Avatar answered Sep 17 '25 18:09

Blossom4696



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!