I’m building a React Native chat app with the following stack:
Frontend: Expo, React Native, MobX
Backend: Node.js, Koa, WebSocket
I want to use the same HTTP server for both REST API and WebSocket connections.
I tried all three options provided by WebSocket to create a new server instance: WebSocket Server Options.
According to the documentation, new WebSocket.Server(options[, callback])
requires that one and only one of port
, server
, or noServer
must be provided, otherwise an error is thrown.
Only initializing the server on a different port (code block 3 below) works in the React Native app. I tried these options in a Create React App, and all three work. Is there a way to use the same server for both WebSocket and HTTP requests?
1.
const server = http.createServer(app.callback());
new WebSocketServer({server})
const server = http.createServer(app.callback());
new WebSocketServer({noServer: true});
server.on('upgrade', (request, socket, head) => {
wss.handleUpgrade(request, socket, head, (ws) => {
wss.emit('connection', ws, request);
});
});
const server = http.createServer(app.callback());
new WebSocketServer({port: 5002});
Here’s my backend setup:
const Koa = require('koa');
const http = require('http');
const WebSocket = require('ws');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
app.use(router.routes()).use(router.allowedMethods());
const server = http.createServer(app.callback());
const wss = new WebSocket.Server({ noServer: true });
server.on('upgrade', (request, socket, head) => {
wss.handleUpgrade(request, socket, head, (ws) => {
wss.emit('connection', ws, request);
});
});
wss.on('connection', (ws) => {
console.log('Client connected');
ws.on('message', (message) => {
console.log(`Received: ${message}`);
ws.send(`Server received: ${message}`);
});
});
server.listen(5001, () => {
console.log('Server running on port 5001');
});
On the React Native side, I try to connect with:
const wsUrl = "ws://local_server_ip_address:5001/ws";
const ws = new WebSocket(wsUrl);
ws.onopen = () => { console.log('WebSocket connected'); };
ws.onmessage = (event) => { console.log('Message from server', event.data); };
ws.onerror = (error) => { console.error('WebSocket error', error); };
ws.onclose = () => { console.log('WebSocket connection closed'); };