I think you can do something like this using a bidi stream. For example, consider the following API:
// A message to be sent from the client to the server when the client changes the state of a component.
message ChangeComponentState {
string name = 1; // Component name.
// ...other fields containing the content of the component change...
}
// A message to be sent from the server to the client to notify the client of a component state change made by another client.
message ComponentStateChangeNotification {
string name = 1; // Component name.
// ...other fields containing the updated contents of the component...
}
service MyService {
rpc ComponentStream(stream ChangeComponentState) returns (stream ComponentStateChangeNotification);
}
The idea here is that the clients will create a bidi stream when they start up and will leave that stream open as long as they are running. Whenever the client needs to change a component, it sends a message on the stream. Whenever the server needs to inform the client of a change to a component made by another client, it will send a message on the stream. Either side can send messages on the stream whenever they want, as long as the stream is open.