Full WebSocket support for real-time applications, Streamlit, Jupyter, and more
stunl natively supports WebSocket connections through HTTP tunnels. WebSocket upgrade requests are automatically detected and handled, enabling bidirectional real-time communication through your tunnel.
WebSocket Support Included
WebSocket support is included in Pro. Perfect for Streamlit, Jupyter notebooks, Socket.IO apps, and any real-time application. Start free.
Upgrade: websocket header
No special configuration needed! WebSocket connections work automatically through HTTP tunnels.
# Your WebSocket server runs on port 8080
$ stunl -port 8080
● STUNL
╭── ◎ ── HTTP
│ HTTPS https://abc123.stunl.io
│ HTTP http://abc123.stunl.io
│ Local localhost:8080
# Connect via WebSocket:
wss://abc123.stunl.io
ws://abc123.stunl.io
# Terminal 1: Start Streamlit
$ streamlit run app.py --server.port 8501
# Terminal 2: Create tunnel
$ stunl -port 8501 -id my-streamlit
# Share with your team:
https://my-streamlit.stunl.io
# Terminal 1: Start Jupyter
$ jupyter notebook --port 8888 --NotebookApp.allow_origin='*'
# Terminal 2: Create tunnel
$ stunl -port 8888 -id my-jupyter
# Access remotely (use the token from Jupyter output):
https://my-jupyter.stunl.io/?token=xxx
// server.js
const io = require('socket.io')(3000, {
cors: { origin: '*' }
});
io.on('connection', (socket) => {
console.log('Client connected');
socket.on('message', (data) => {
io.emit('message', data);
});
});
// Start and tunnel
$ node server.js
$ stunl -port 3000 -id chat
// Client connection
const socket = io('https://chat.stunl.io');
# main.py
from fastapi import FastAPI, WebSocket
app = FastAPI()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Echo: {data}")
# Start and tunnel
$ uvicorn main:app --port 8000
$ stunl -port 8000 -id api
# Connect to:
wss://api.stunl.io/ws
When using multi-port tunneling, you can route WebSocket connections alongside HTTP traffic using path-based routing.
# Frontend on 3000, WebSocket server on 3001
$ stunl -id myapp -ports "web:3000:http,ws:3001:http"
● STUNL
╭── ◎ ── HTTP web
│ HTTPS https://myapp.stunl.io
│ Local localhost:3000
╭── ◎ ── HTTP ws
│ HTTPS https://myapp.stunl.io/ws
│ Local localhost:3001
# Frontend: https://myapp.stunl.io
# WebSocket: wss://myapp.stunl.io/ws
| Feature | Pro |
|---|---|
| WebSocket support | ✓ |
| Connection timeout | Unlimited |
| Monthly bandwidth | 25 GB |
Always connect to wss:// URLs. stunl provides TLS termination automatically, ensuring encrypted connections.
Implement reconnection logic in your WebSocket client. Network interruptions can drop connections, and your client should gracefully reconnect.
If your WebSocket server uses CORS, allow the stunl domain or use origin: '*' for development.
stunl supports WebSocket ping/pong frames. Your server should respond to ping frames to keep connections alive through proxies and load balancers.
Make sure you're using the correct protocol:
wss:// for HTTPS tunnels (recommended)ws:// for HTTP tunnelsSome browsers close idle WebSocket connections. Implement ping/pong or heartbeat messages to keep the connection active.
If your page is served over HTTPS, you must use wss:// for WebSocket connections. Browsers block ws:// on HTTPS pages.