Setup a WebSocket Server with Cloudflare
1. What WebRTC is
WebRTC (Web Real-Time Communication) is a set of APIs built into modern browsers that lets two peers (e.g., two users in React apps) connect directly to each other to exchange:
The magic: it works peer-to-peer, not through a central server (though servers are still used to help them connect).
2. The Core Pieces
For two apps to talk over WebRTC, you need:
a) Signaling
b) ICE / STUN / TURN
c) PeerConnection
d) Data Channel
3. Flow of a Connection
Hereβs what happens when User A chats with User B:
4. Chat Example (DataChannel)
On Peer B:
5. File Transfer Example
WebRTC DataChannels support binary blobs, so you can send files chunk-by-chunk:
Receiver just listens for binary data and reconstructs the file.
6. Why This Is Cool
π So in your React app, the βchat + file transferβ works because:
1. What signaling needs
Signaling is just about exchanging:
This requires bidirectional, asynchronous communication between peers (via your server).
2. Options compared
β WebSockets
β οΈ HTTP (long polling / REST)
3. Hybrid approach
Some apps start with HTTP POST to register a peer (like βhereβs my offerβ) and then switch to WebSocket or another channel for ongoing exchange. But for your React chat/file transfer app, thatβs overkill β just stick with WebSockets.
4. Rule of thumb
π So for your use case (chat + file sharing between React apps), WebSockets are definitely the better choice for signaling.
Would you like me to show you a minimal WebSocket + WebRTC signaling server (Node.js) that you could plug into your React app as a starting point?
Β
1. Why you can use PHP
2. Options for PHP WebSocket servers
3. Minimal Ratchet Example
Install via Composer:
Server (server.php):
Run it:
4. Connecting from React
In your React app:
5. Is PHP the best choice?
Β
1. Does Cloudflare support WebSockets?
β Yes.
2. How Cloudflare Tunnel affects it
So yes, your PHP WebSocket server will work fine through Cloudflare Tunnel.
3. Things to watch out for
4. Example Setup
β Result:
1. Prerequisites
2. Create a named tunnel
This generates a tunnel UUID and credentials file, usually at:
3. Configure the tunnel (YAML)
Create a config file at ~/.cloudflared/config.yml
:
Explanation:
4. Connect the tunnel to Cloudflare
Run:
This tells Cloudflare DNS to point signal.example.com
β your tunnel.
5. Run the tunnel
Foreground (debugging):
Background (production):
6. React client connection
Now in your React app, connect securely:
7. Important notes
π With this setup, you get:
Done β I created a code + instructions document in the canvas titled Webrtc-php-ratchet-signaling-and-react. It includes:
Open the canvas (the document named Webrtc-php-ratchet-signaling-and-react) to copy the server and client code and follow the run instructions.
1. Do you need special Nginx config?
It depends how youβre exposing your WebSocket server:
2. Does the PHP Ratchet server need to be persistent?
Yes β
That means:
Example systemd
unit (/etc/systemd/system/ratchet.service
):
Then:
3. Summary
π Why Node.js fits better than PHP Ratchet for signaling
π’ Minimal Node.js WebSocket signaling server
π React client-side example
π Deployment with Cloudflare Tunnel
β So in your case:
π§ Options if port 8080 is already taken
β Recommended
If this signaling server is dedicated, Option 1 (different port + Cloudflare Tunnel mapping) is the cleanest and least error-prone. You donβt even need to touch your existing app or Nginx config.
1. Example setup
2. Cloudflare Tunnel config file (/etc/cloudflared/config.yml
)
π Notes:
http://
is for normal HTTP traffic.
ws://
is for raw WebSockets (Node signaling server).
http_status:404
ensures unmatched requests donβt hang.
3. Start the tunnel
If your tunnel is already created:
If not, create one first:
4. DNS setup in Cloudflare
5. Verify
π This way you donβt worry about port clashes at all β every local service can run on its own port, and Cloudflare maps them to different hostnames.
1. Create the systemd unit file
Create a new file:
Paste this:
π Replace
my-tunnel-id
with the name or UUID of your tunnel (you can see it incloudflared tunnel list
).
You might also need to change/usr/bin/cloudflared
if itβs installed elsewhere (which cloudflared
will tell you).
2. Create a dedicated user (optional, but safer)
3. Enable and start
4. Check status & logs
5. Verify itβs working
β With this, your tunnel will:
1. Create the service file
Save as:
Example unit:
2. Adjust paths and user
3. Enable and start
4. Check logs
5. Auto-restart on crash
The Restart=always
+ RestartSec=5s
ensures that if your Node app crashes, systemd will bring it back up in 5 seconds.
β At this point:
π§ Target Setup
1. PHP-FPM + Nginx config (API + frontend)
Example Nginx site config (e.g. /etc/nginx/sites-available/example.conf
):
Here:
React build served on localhost:3000
PHP-FPM API served on localhost:8080
2. Node.js signaling server
Say you have /var/www/signaling/server.js
:
Runs on localhost:9000.
3. Cloudflare Tunnel config (/etc/cloudflared/config.yml
)
4. Services managed by systemd
Cloudflared
/etc/systemd/system/cloudflared.service
Node signaling server
/etc/systemd/system/signaling.service
5. Enable & start everything
6. Result
β
With this, you have an all-in-one blueprint: PHP + Nginx + Node + Cloudflare Tunnel living together.
You never need to expose raw ports β just map each subdomain to the right service in your config.yml
.
π’ Enhanced Node.js Signaling + Messaging Server
π‘ React Client Example
Connecting & joining
Sending chat
File transfer (chunked)
Receiving chat / files
π Key Points
β This way your Node server is: