Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handleIPCMessage only sends replies to electron main frame #145

Closed
JoeHartzell opened this issue Jun 13, 2023 · 4 comments · Fixed by #146
Closed

handleIPCMessage only sends replies to electron main frame #145

JoeHartzell opened this issue Jun 13, 2023 · 4 comments · Fixed by #146

Comments

@JoeHartzell
Copy link
Collaborator

JoeHartzell commented Jun 13, 2023

Summary

I have a use case that involves using iframes and tRPC to communicate between each frame and the main thread. After spending some time debugging it seems that handleIPCMessage replies to the sender using event.sender.send which will always reply to the main frame.

References

  • Electron Docs

    • To send an asynchronous message back to the sender, you can use event.reply(...). This helper method will automatically handle messages coming from frames that aren't the main frame (e.g. iframes) whereas event.sender.send(...) will always send to the main frame.

  • handleIPCMessage code

Solution

I think the solution here is pretty simple. handleIPCMessage should be able to use event.reply to respond to incoming events as stated by the Electron docs. This would also involve updating the types on the event parameters to use ipcMainEvent instead of IpcMainInvokeEvent.

Example

Current implementation

import { IpcMainInvokeEvent } from 'electron'
export async function handleIPCMessage<TRouter extends AnyRouter>({
  router,
  createContext,
  internalId,
  message,
  event,
  subscriptions,
}: {
  router: TRouter;
  createContext?: (opts: CreateContextOptions) => Promise<inferRouterContext<TRouter>>;
  internalId: string;
  message: ETRPCRequest;
  event: IpcMainInvokeEvent; // OLD
  subscriptions: Map<string, Unsubscribable>;
}) { 
// ...
}

Suggested change

import { IpcMainEvent } from 'electron'
export async function handleIPCMessage<TRouter extends AnyRouter>({
  router,
  createContext,
  internalId,
  message,
  event,
  subscriptions,
}: {
  router: TRouter;
  createContext?: (opts: CreateContextOptions) => Promise<inferRouterContext<TRouter>>;
  internalId: string;
  message: ETRPCRequest;
  event: IpcMainEvent; // NEW
  subscriptions: Map<string, Unsubscribable>;
}) { 
// ...
}

Contributing

Would be more than happy to make a PR with the suggested changes above.

Versions

  • electron-trpc: 0.5.0
  • electron: 24.4.1
  • node: 16.14.0
  • pnpm: 8.6.1
JoeHartzell added a commit to JoeHartzell/electron-trpc that referenced this issue Jun 13, 2023
@JoeHartzell
Copy link
Collaborator Author

Just confirmed that the PR resolves the issue and my frames now successfully communicate! 🎉 It might be worth following up this issue by adding an example to the repo using iframes.

@JoeHartzell
Copy link
Collaborator Author

Just giving this a friendly bump @jsonnull . Would love to see this merged as I think it blocks multi-window support as well. Also more than happy to help on any other roadmap items. This is by far the best way to work with electron ipc communication.

@jsonnull
Copy link
Owner

Hey, thanks for the friendly bump and all the effort here. I'll get this merged in and get a release out. If you're interested in contributing more, let's chat sometime!

@jsonnull
Copy link
Owner

This fix is released in electron-trpc@0.5.1. Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants