The Redwood Core team would like to start doing more experiments with things that could go into the framework if there is enough interest and excitement in the community.
Experiments are quick and dirty. Super rough around the edges. Just to play around with what’s possible. Please try them out in a throwaway project or on a throwaway branch in your real project.
WebSocket experiment
The first experiment is WebSockets support for realtime capabilities.
Please let us know if this is something you’d use. And when you’ve tried it, tell us what you loved about the experience and what you hated
How to try
Quick steps to try the WebSockets experiment
yarn create redwood-app --ts --git rw-ws-experiment
cd rw-ws-experiment
yarn dlx rw-setup-ws
yarn rw g page WebSocket
Replace all content of the newly created page with this:
import { useState } from 'react'
import { useWsContext } from 'src/components/WsContext/WsContext'
const WebSocketPage = () => {
const [name, setName] = useState('')
const [message, setMessage] = useState('')
const ws = useWsContext()
return (
<>
<label>
Name:{' '}
<input
value={name}
onChange={(event) => {
setName(event.target.value)
}}
/>
</label>
<br />
<br />
<label>
Message:{' '}
<input
value={message}
onChange={(event) => {
const message = event.target.value
// Set the message in component state to make the input
// value update immediately
setMessage(message)
// Send to the server to update all clients (including
// this one)
ws.sendMessage(name, message)
}}
/>
</label>
<hr />
<ul>
{Object.entries(ws.clients).map(([clientId, clientMessage]) => (
<li key={clientId}>
{clientId}: {clientMessage}
</li>
))}
</ul>
</>
)
}
export default WebSocketPage
Run yarn rw dev and go to http://localhost:8910/web-socket in two different browser windows and see the text everyone is typing update in realtime.
I got into a little more detail on my blog. (The blog post was written before I wrote the rw-setup-ws command, so it also includes all the steps the setup command now does for you.)
I am doing some basic research that might result in a wide-spanning application connecting the IoT cloud and a “classic” distributed app living in a different cloud:
In this schema, the RW app would maintain real-time communications with the “Notehub” cloud maintained by Blues Wireless. Building such a system (targeting Healthcare space initially) takes a lot of my time, so I a not sure how responsive can I be to your needs, @Tobbe.
Why would I? I reacted to your “experiment” post so happily as I understand to have something to use in my prototype (the yellow rectangle) below:
If I participate as your “user & tester” providing a different context, I would avoid “rolling my own” simply because it would save me time and I have more faith in your networking expertise than my own
I’m sorry, I should have been more clear. When I said “roll your own”, I meant “do what I did in my experiment”, because I wrote my own WS code, and, perhaps more importantly, ended up setting up my own hosting solution to get it all working when deployed. I never wrote about that last part in my blog post, because I was planning on doing a follow-up post on that. Haven’t had time for that yet though. But the unfortunate truth is that it’s really really difficult to host a WS server that can handle a big load and that is resilient to failures.
Good suggestion that I am happy to take to heart. As I am traveling to Croatia (read the Adriatic Sea) to stay a month, I expect to be silent on my communication channels
I also forced pm2 to only run one instance of the api server so that all connections always hit the same server. The default is to run two instances of the server to get some load balancing. But that was a problem for websockets as the connection only lives on one of the servers.
I think the way I fixed my pm2 config was setting instances: 1 and exec_mode: 'fork' in ecosystem.config.js
And that right there is another reason you shouldn’t be setting this up yourself like this. For a proper production system you need to be able to scale your servers and not just force it to be a single instance like that.
Nice feature! However I didn’t really understand what do you mean by “not ready for production”. If I try to build this application and deploy it on localhost it doesn’t work?
It works. But I wouldn’t recommend running this on a production site with actual users. Like it’ll probably work fine with a handful of users, but for a serious site better infra is needed