I'm trying to lay out an idea for a project, where a client-side GUI can be developed in python, and the GUI can be driven by a backend in potentially any other language, over RPC. More specifically, right now I am working with PyQt on the client side, and Go as the initial backend.
Here are my goals:
- PyQt client
- Roles: View, Controller
-
Oneway calls (SIGNAL/SLOT), such as:
button.clicked -> RPC.handleSignal
-
Request/Reply RPC, such as:
rowCount = model.rowCount -> RPC.call.model.rowCount
- Agnostic backend (Go in this case)
- Roles: Controller, Model
-
Oneway calls (Emit SIGNAL), such as:
model.dataChanged -> RPC.emitSignal
I refer to each of these as having controller roles becase a user could define signal/slot connections in the GUI client side, or the backend could define its own signal/slot connections over RPC, assuming knowledge about the view on the client side. It would depend solely on how the user wants to set up the controller.
I am looking at Thrift right now, vs say a lighter weight basic rpc without an IDL. But mainly my question is whether it would be a messy approach to try and do Thrift as two .thrift files, with client/server <----> client/server (two connections), in order to get the bi-directional functionality? The benefit I see with Thrift is the IDL, so that I can build my interface specifically, and backend code can just implement the parts they want.
Does anyone have a recommendation for a solution to this? Two Thrift interfaces? One Thrift interface, that provides a service to let the client establish a second simple socket to receive oneway calls from the server? Or is Thrift somewhat even overkill here? While the backend -> GUI interface is really only a single service function, the GUI -> backend could expand a bit (modelHandlers, slotHandlers, general server status queries).
(Edit) More Thoughts
Part of me is thinking that the pattern could be done with any RPC framework, and it would be like this?
- Backend server process starts; listens on port
- Client GUI starts; connects to server RPC; listens on new port; sends port to server via RPC call
- Server receives port from client, and binds to it for a second RPC connection
- Client and Server have 2 connections, for bi-directional RPC