-
-
Notifications
You must be signed in to change notification settings - Fork 325
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
Allow server-side components to send messages to client-side components #975
Comments
Tangentially related |
The name
The design below would allow for an event-driven architecture when possible, inspired by With any design we make, we're going to need to be careful about our asyncio cancellation policy for messengers. This will extend to us thinking deeper about async from dataclasses import dataclass
from reactpy import component, hooks
@dataclass
class DataMessenger:
def __init__(self, *args, **kwargs):
self.args = args or ()
self.kwargs = kwargs or {}
async def send(self, message):
"""This method typically isn't overridden."""
...
async def recieve(self, message):
"""This method typically gets overriden with custom user behavior."""
...
async def register(self, ... ):
"""This method typically isn't overridden. Used to register a message handler to a component."""
...
def use_messenger(messenger: DataMessenger) -> DataMessenger:
"""This is a hook that allows users to communicate to client-side components.
The given `messenger` will be registered to the current component.
"""
MESSENGER_CONTEXT: list = hooks.use_context(...)
# A given `Messenger` should persist throughout the entire lifecycle of a component
if messenger not in MESSENGER_CONTEXT: # Not a usable implementation, but you get the point
messenger.register(...)
# Update `args`/`kwargs` on each component re-render.
else:
messenger.args = MESSENGER_CONTEXT[0].args
messenger.kwargs = MESSENGER_CONTEXT[0].kwargs
# Give the user access to the registered messenger, if he wants to do some shenanigans within `use_effect`.
return messenger
@component
def example():
# If the user only wants to be event driven, then he won't need to save a `messenger = ...` variable
messenger = use_messenger(DataMessenger(example_value=1))
@hooks.use_effect
async def send_message():
# Using `messenger` methods here would rely on our half-baked async `use_effect`
# I think this might be an argument to fleshing out async effects
await messenger.send("Hello, World!") |
I think this is true. One could imagine a server-side component that constructs several channels in order to communicate with different client-side components. |
If we're allowing support for multiple communicators, imo that narrows it down to the following:
I updated the example above to better outline how persistence of |
Current Situation
Presently, custom client-side components are able to send events back to the server. However, it is not possible to send events from server-side components to client-side ones.
Proposed Actions
Now that custom JS components have the ability to register callbacks with the client this should be technologically feasible. With that said, while users can listen in on particular message types, there is no concept of a message "target". We could achieve this by having message types of the form
server-event:<the-target>
, but this seems like a bit of a hack. Perhaps we can allow (require?) a nullabletarget
field for this purpose.Before diving into all those details though, we need to work out exactly what this interface should look like.
I can imagine having an interface similar to:
where
custom_js_component
would then subscribe to messages of the typechannel-message
and targetchannel.id
.The text was updated successfully, but these errors were encountered: