NewSchokr 13 is here. A whole new UI, seven locations, snapshots and more. Read more →

How to run WebSockets (ws, Socket.IO) on Schokr

Run a WebSocket server with ws, Socket.IO, Bun or Python on Schokr by sharing your HTTP port, and connect clients with ws:// URLs.

Updated · 1 min read

WebSockets work on Schokr like any other TCP traffic: run your WebSocket server on 0.0.0.0 and your allocated port, and connect from clients with ws://<server-address>:<port>. The simplest setup shares one port between your HTTP server and WebSockets.

Why share one port

Each server starts with one port allocation. A WebSocket connection starts as a normal HTTP request and is then upgraded, so one port can serve both your web pages and your sockets. If you really need a separate port, extra allocations cost 25 credits each (unlimited with Schokr One).

Node.js with ws

const http = require('http')
const { WebSocketServer } = require('ws')

const server = http.createServer((req, res) => res.end('ok'))
const wss = new WebSocketServer({ server })

wss.on('connection', (socket) => {
  socket.on('message', (data) => socket.send(`echo: ${data}`))
})

const port = Number(process.env.APP_PORT || 3000)
server.listen(port, '0.0.0.0')

With Express, pass the server returned by app.listen(...) to new WebSocketServer({ server }).

Socket.IO

const { createServer } = require('http')
const { Server } = require('socket.io')

const httpServer = createServer()
const io = new Server(httpServer, {
  cors: { origin: ['https://your-frontend.example'] },
})

io.on('connection', (socket) => {
  socket.on('chat', (msg) => io.emit('chat', msg))
})

httpServer.listen(Number(process.env.APP_PORT || 3000), '0.0.0.0')

The cors option is needed when your web page is served from a different origin. See CORS basics.

Bun

Bun.serve({
  hostname: '0.0.0.0',
  port: Number(process.env.APP_PORT || 3000),
  fetch(req, server) {
    if (server.upgrade(req)) return
    return new Response('ok')
  },
  websocket: {
    message(ws, message) {
      ws.send(`echo: ${message}`)
    },
  },
})

Python (FastAPI)

from fastapi import FastAPI, WebSocket

app = FastAPI()

@app.websocket("/ws")
async def ws(socket: WebSocket):
    await socket.accept()
    while True:
        text = await socket.receive_text()
        await socket.send_text(f"echo: {text}")

Run it with uvicorn[standard] installed so WebSocket support is included. See FastAPI deployment.

Connecting from a client

const socket = new WebSocket('ws://<server-address>:<port>')
socket.onmessage = (e) => console.log(e.data)

A page loaded over https:// cannot open an insecure ws:// connection; browsers block it as mixed content. Schokr does not terminate TLS for you, so for wss:// you need a proxy in front that handles HTTPS. See using your own domain.

Keeping connections alive

  • Idle connections can be dropped by proxies and networks. Send a ping every 30 seconds or so (Socket.IO does this automatically).
  • Make clients reconnect automatically after your server restarts.
  • State held in memory, such as connected users, is lost on restart. Persist anything important.