[Backend Note] Using socket.io or ws in NodeJS

Simple websocket usage in NodeJS and Vue

Posted by Jamie on Tuesday, January 31, 2023

WebSocket in NodeJS and VueJS

Introduction to Websocket

According to the definition on wiki, websocket is a network transport protocol based on TCP. In a normal GET/POST http request, after the data has been transferred, the TCP connection is closed via the four-way handshake; but in the WebSocket protocol, once the client and server complete the TCP handshake, they can maintain a long-lived connection.

Why do we need the websocket protocol? Mainly because of a limitation of HTTP: HTTP requests can only be initiated by the client. As a result, if the client needs to respond to changes on the server, it must keep firing requests at an interval to “listen” for changes on the server; with websocket, however, a long-lived connection can be established: the client fires one request to set up the connection, and then whenever the server has new data or some change, the server can push it through this connection directly, and the client can react to it.

Using websocket in NodeJS

From the Awesome List of websocket for NodeJS you can see that NodeJS has many websocket libraries; ranking by stars, socket.io and websockets/ws are far ahead of the rest (57.5k and 19.4k on 20230131), so let’s demo with these two together with express.

  • Socket.io

    // app.js
    const express = require('express')
    const http = require('http')
    const socket = require('socket.io')
    
    const app = express()
    // use express to handle http server
    const server = http.createServer(app) 
    const io = socket(server)
    
    // while socket connect, send a 'hello world text' 
    const onConnection = (socket) => {
    	socket.send("hello world ")
    	console.log('Socket.io init success')
    }
    io.on("connection", onConnection)
    
    server.listen(3000, () => {
    console.log('Server listening at port 3000');
    })
    
  • ws

    // app.js
    
    const express = require('express')
    const { WebSocketServer } = require('ws')
    
    const app = express()
    // use express to handle http server
    const server = http.createServer(app) 
    
    const wss = new WebSocketServer({ server })
    
    wss.on('connection', ws => {
    	ws.send("hello world ")
    	console.log('Socket.io init success')
    })
    server.listen(3000, () => {
    console.log('Server listening at port 3000');
    })
    
    

As you can see, there is not much difference between the two on the NodeJS side; the difference is more about package size and performance. (socket.io: 276.6k, ws: 43.8K)

Using Websocket on the Frontend (with Vue as an example)

  • Socket.io

The most attractive thing about Socket.io has been that it provides wrappers for both the server and the browser, so you can use it directly:

// useSocket.ts

import { io } from 'socket.io-client'

export default function useSocket() {
    const socket = io('ws://localhost:3000')
    return {
        socket,
    }
}
// Demo.vue
import useSocket from '../utils/useSocket'
...
setup(){
	const { socket } = useSocket()
    onMounted(() => {
	    socket.on('connect', (data) => {
	        console.log(data)
	    })
	})
	return {}
}
  • ws

From the official docs and other people’s demos online, ws does not currently provide a wrapper for client-side use, so you can only wrap the browser’s native WebSocket; the simplest approach is to use the native API directly:

// useSocket.ts
export default function useSocket() {
    const socket = new WebSocket('ws://localhost:3000')
    return {
        socket,
    }
}
// Demo.vue
import useSocket from '../utils/useSocket'
...
setup(){
	const { socket } = useSocket()
    onMounted(() => {
    	socket.onmessage( (event) =>{
    		console.log(`socket data:${event.data}`)
    	} )
	})
	return {}
}

ChangeLog

  • 20230131-init
  • 20260501–translate by claude code