2

Currently I am introducing worker_threads to a game I am developing. Thea idea is to have each game room in a separate thread, so that they can be processed in parallel (yeah I know that will only really happen if there isn't more threads than cores).

However, I cannot get socket.io to work with worker_threads. So far I have tried the following:

1. Create the socket.io server within the server:

server.js

const { Worker, isMainThread } = require("worker_threads");

const express = require("express");
const app = express();
app.use(express.static(__dirname));

app.post("/newGame", (request, response) => {
  let roomCode = request.query.room_code;
  const worker = new Worker("./server-worker.js", {
    workerData: {
      roomCode: roomCode
    },
  });
});

app.listen(8080, () => {
  console.info("Server started on http://localhost:8080");
});

server-worker.js

const { parentPort, workerData, threadId } = require("worker_threads");


const server = require("http").createServer();
const io = require("socket.io")(server);

server.listen(8080, () => {
  console.info("Server socket.io on port 8080");
});

io.on("connection", (socket) => {
  console.log(`Client with ID ${socket.id} connected to thread with ID ${threadID}`);
});

This results in the browser logging this: GET http://localhost:8080/socket.io/?EIO=3&transport=polling&t= 404 (Not Found)

Also even if I got Express to forward the polling request to the worker I am guessing that I would not be able to open more than one room since the port would already be in use.

2. Create socket.io instance in main thread and pass it on

server.js

const { Worker, isMainThread } = require("worker_threads");

const express = require("express");
const app = express();
app.use(express.static(__dirname));

const server = require("http").createServer(app);
const io = require("socket.io")(server);

app.post("/newGame", (request, response) => {
  let roomCode = request.query.room_code;
  const worker = new Worker("./server-worker.js", {
    workerData: {
      roomCode: roomCode,
      io: io
    },
  });
});

However, this does not work since I get a DataCloneError because worker_threads can only send native objects to workers.

Questions:

  • Is there an easier way to accomplish what I am doing? I.e.: Am I just using the wrong framworks?
  • Is there a way to get socket.io working with threads? I already saw a documentation on using it with node.js clusters using a Redis instance but that seems overkill for the problem at hand since I do not have multiple processes/ nodes.

1 Answer 1

1

Node's worker threads are not suitable for your purpose. They're for doing long-running computations, not handling network connections.

Also, it probably does not make sense to assign your rooms to particular server resources. Node is good at concurrently handling multiple app contexts and so is socket.io.

To scale up your app to use more processor cores, node offers clustering. To use a cluster you'll need to sort out session stickiness.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! I am completely new to both JavaScript and game dev so this input is very valuable. I had the impression this was a good idea from another post here: softwareengineering.stackexchange.com/questions/379272/…
If you were writing your code in C# / dotnet / unity, threads would be a reasonable choice for you: in that language, runtime, and tool chain threads can do both IO and computing concurrently, and they're much cheaper to create than they are in dotnet. But you would still be wise to assign your threads to connected users, not to game rooms. The C# APIs for socket.io naturally fit work with a thread per connection. Using async/ await you can, and should, emulate that in node. But you won't be using real threads, instead node-style asynchronous programming.
hi, how did you solve this? since worker_threads can only send native objects to workers, what if you use parentPort.postMessage(..) to send the data back to mainThread and do it in ` worker.on("message", (msg) => { .... })`? wouldnt that solve the issue?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.