vendredi 24 juillet 2020

Best practices in structuring Node.js & Socket.io app?

Currently I'm developing a node server which uses websockets for communication. I'm used to applying MVC (or MC) pattern in my apps. I'd like to structure my socket.io in similiar way and my question is how to do this in the best way?

For now I have something like this:

utils/socket.ts:

type IO = null | SocketIO.Server;
let io: IO;

export function init(ioServer: IO) {
  io = ioServer;
}

export function getIO(): IO {
  return io;
}

app.ts:

import express from 'express';
...

import { init } from './utils/socket';
import startSockets from './controllers';

const app = express();


...

const server = app.listen(process.env.PORT || 5000);

const io = socketio.listen(server);

if (io) {
  init(io);
  io.on('connect', startSockets);
}

controllers/index.ts:

import { onConnect } from './connect';
import { getIO } from '../utils/socket';

export default function (socket: SocketIO.Socket) {
  const io = getIO();
  socket.on('connect-player', onConnect);
}

controllers/connect.ts:

 import Player from '../models/Player';

  export const onConnect = async function (this: SocketIO.Socket, name: string) {
  const player = await Player.create({ name });

  this.broadcast.emit('player-connected', `Player ${name} joined the game!`);
  this.emit(
    'player-connected',
    `Congratulations ${name}, you successfully joined our game!`,
    player,
  );

  this.on('disconnect', onDisconnect.bind(this, player.id));
};

const onDisconnect = async function (this: SocketIO.Socket, playerId: string) {
  const player = await Player.findById(playerId);
  await player?.remove();
  this.broadcast.emit(
    'player-connected',
    `Player ${player?.name} left our game!`,
  );
};

I'm not sure about using 'this' in my controller and about that singleton pattern in utils/socket.ts. Is that proper? The most important for me is to keep the app clear and extensible.

I'm using express and typescript. Player.ts is my moongoose schema of player.

Aucun commentaire:

Enregistrer un commentaire