Consider SSE to enable server->client http subscriptions
Problem
Reading through the #532 PR it occurred to me that the JSON-RPC notification system only works one way, from client to server. Most of the time you want it to be from server to client. Although nothing about the spec says which side is which, in a browser this basically means the browser is the client. One interesting approach could be to use Server Sent Events. This would allow for stateless load balance-able subscriptions that could work with HTTP2. From what I'm seeing though I'm not sure if it would technically fall under a JSON-RPC complaint spec; though you probably can treat as a server to client notification. Nice thing is this is already built into browsers with polyfills available for node and most languages. I think you'd create/cancel as you do currently but the client would also fetch on a new route /subscription/3nxu4ex234. Know this is separate from the websocket implementation but SSE isn't a well known. The major downside of the SSE spec as it stands is the text only protocol (compared to binary for websockets) but in a JSON-RPC context the point is moot. <sub>TRP-63</sub>
Unverified for your environment
Select your OS to check compatibility.
1 Fix
Implement Server-Sent Events for Server-to-Client Notifications
The current JSON-RPC notification system only supports one-way communication from client to server, limiting the ability to push updates from the server to the client. Server-Sent Events (SSE) provide a solution for enabling real-time notifications from the server to the client over HTTP, allowing for stateless, load-balanced subscriptions.
Awaiting Verification
Be the first to verify this fix
- 1
Create SSE Endpoint
Develop a new endpoint on the server to handle SSE connections. This endpoint will be responsible for sending notifications to subscribed clients.
javascriptapp.get('/subscription/:id', (req, res) => { res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); const id = req.params.id; // Logic to subscribe the client to notifications // Example of sending a message setInterval(() => { res.write(`data: {"message": "Update from server"}\n\n`); }, 1000); }); - 2
Modify Client to Connect to SSE
Update the client-side code to establish a connection to the new SSE endpoint. This will allow the client to receive real-time notifications from the server.
javascriptconst eventSource = new EventSource('/subscription/3nxu4ex234'); eventSource.onmessage = function(event) { const data = JSON.parse(event.data); console.log('Received update:', data.message); }; - 3
Implement Subscription Management
Add logic to manage subscriptions on the server, including creating and canceling subscriptions based on client requests. This ensures that clients can subscribe and unsubscribe as needed.
javascriptapp.post('/subscribe', (req, res) => { const subscriptionId = generateUniqueId(); // Logic to store subscription res.json({ subscriptionId }); }); app.post('/unsubscribe', (req, res) => { const { subscriptionId } = req.body; // Logic to remove subscription res.sendStatus(200); }); - 4
Test SSE Functionality
Conduct tests to ensure that the SSE implementation works correctly. Verify that clients receive notifications as expected and that subscriptions can be created and canceled without issues.
javascript// Use a tool like Postman to test the /subscribe and /unsubscribe endpoints. // Check browser console for received messages from the SSE connection.
Validation
Confirm that the client receives updates from the server by checking the browser console for messages. Additionally, ensure that subscriptions can be created and canceled successfully by testing the relevant endpoints.
Sign in to verify this fix
Environment
Submitted by
Alex Chen
2450 rep