ale917k
ale917k

Reputation: 1768

Socket.io keep connection up when server get refreshed / turned down

Premising I'm new to sockets, I'm trying to set up the first configuration on server (Node w/Express).

While doing so, I encountered an issue where nodemon crashes every time I save, by returning Error: listen EADDRINUSE: address already in use :::8080.

Here the server implementation:

import express from "express";
import cors from "cors";
import { Server, Socket } from "socket.io";
import { createServer } from "http";
import morgan from "morgan";

// App configuration
const app = express();
const server = createServer(app);
const io = new Server(server);
const port = process.env.PORT || 8080;

// Middlewares
app.use(cors());
app.use(express.json());
app.use(morgan("combined"));

// Socket connection
io.on("connect", (socket: Socket) => {
  socket.send("test");
});

server.listen(port, () => {
  console.log(`Server is up and running on ${process.env.NODE_ENV} - port ${port}`);
});

I would think that happens as the socket.io connection never get closed / disconnected, leaving the server instance up listening.

I had a look around and found many q/a that were suggesting commands to find and kill the process, but I'd need a solution able to disconnect the socket automatically every time the express server gets turned down.

I tried the following:

io.on("disconnect", () => {
  io.sockets.disconnect();
}

As suggested here, but TS complains about io.sockets.disconnect() with a Property 'disconnect' does not exist on type 'Namespace<DefaultEventsMap, DefaultEventsMap>'.ts(2339).

Any idea how this should be tackled?

Upvotes: 0

Views: 815

Answers (1)

srknzl
srknzl

Reputation: 787

I think there may be an issue in socket io initialization. Can you try this type of initialization showed at https://socket.io/get-started/chat#Integrating-Socket-IO:

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

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {
  console.log('a user connected');
});

server.listen(3000, () => {
  console.log('listening on *:3000');
});

So basically pass server object to the default import from socket io like this(right now, you are using "Server" inside socket.io ):

import express from "express";
import cors from "cors";
import ioDefault, { Server, Socket } from "socket.io";
import { createServer } from "http";
import morgan from "morgan";

// App configuration
const app = express();
const server = createServer(app);
const io = ioDefault(server);
const port = process.env.PORT || 8080;

// Middlewares
app.use(cors());
app.use(express.json());
app.use(morgan("combined"));
// ...

UPDATE:

The issue was another server running on the same port. To check which process is running on a specific port you can run

netstat -anpe | grep "8080" | grep "LISTEN"

if netstat is not installed run sudo apt install net-tools in debian based systems(ubuntu, fedora and others)

you can then kill it with its pid:

kill -9 5454

Upvotes: 2

Related Questions