Skip to content

Namespaces

Video Lecture

Namespaces Namespaces

Description

It is possible to have one socket server, and have several types of clients connect to it.

To separate command listeners for different types of applications, connecting to the one socket server, you can use namespaces.

Note that the default namespace when connecting to a Socket.IO server will be "/".

const socket = io()

Is the same as,

const socket = io('/')

If you wanted the one socket server, to deliver random numbers, and also run the collaboration painter program, then the namespaces you could set up may be rng and colabPainter.

./src/server/server.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { createServer } from 'http'
import { Server } from 'socket.io'
import * as express from 'express'
import * as path from 'path'

const port = 3000

const app = express()
app.use(express.static(path.join(__dirname, '../client')))

const server = createServer(app)

const io = new Server(server)

io.of('/rng').on('connection', (socket) => {
  console.log('a user connected : ' + socket.id)

  socket.emit('message', 'Hello ' + socket.id)
})

io.of('/colabPainter').on('connection', (socket) => {
  console.log('a user connected : ' + socket.id)

  socket.on('draw', (message) => {
    socket.broadcast.emit('draw', message)
  })
})

server.listen(port, () => {
  console.log('Server listening on port ' + port)
})

setInterval(() => {
  io.of('/rng').emit('message', Math.floor(Math.random() * 100))
}, 1000)

./src/client/rng.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import { io } from 'socket.io-client'

const socket = io('/rng')

socket.on('connect', () => {
  document.body.innerText = 'Connected : ' + socket.id
})

socket.on('message', (message) => {
  document.body.innerHTML += '<p>' + message + '</p>'
  window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' })
})

./src/client/colabPainter.ts

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
import { io } from 'socket.io-client'

const socket = io('/colabPainter')

socket.on('draw', (message) => {
  prevX = message[0]
  prevY = message[1]
  currX = message[2]
  currY = message[3]
  color = message[4]
  draw()
})

let prevX = 0,
  currX = 0,
  prevY = 0,
  currY = 0

let color = 'black'
const thickness = 10

const canvas = document.getElementById('canvas') as HTMLCanvasElement
canvas.width = window.innerWidth
canvas.height = window.innerHeight

const ctx = canvas.getContext('2d') as CanvasRenderingContext2D

window.addEventListener('resize', function () {
  if (window.innerWidth > 0 && window.innerHeight > 0) {
    const data = ctx.getImageData(0, 0, window.innerWidth, window.innerHeight)
    canvas.width = window.innerWidth
    canvas.height = window.innerHeight
    ctx.putImageData(data, 0, 0)
  }
})

const greenButton = document.getElementById('greenButton') as HTMLDivElement
greenButton.addEventListener('click', () => {
  color = 'green'
})
const blueButton = document.getElementById('blueButton') as HTMLDivElement
blueButton.addEventListener('click', () => {
  color = 'blue'
})
const redButton = document.getElementById('redButton') as HTMLDivElement
redButton.addEventListener('click', () => {
  color = 'red'
})
const yellowButton = document.getElementById('yellowButton') as HTMLDivElement
yellowButton.addEventListener('click', () => {
  color = 'yellow'
})
const orangeButton = document.getElementById('orangeButton') as HTMLDivElement
orangeButton.addEventListener('click', () => {
  color = 'orange'
})
const blackButton = document.getElementById('blackButton') as HTMLDivElement
blackButton.addEventListener('click', () => {
  color = 'black'
})
const whiteButton = document.getElementById('whiteButton') as HTMLDivElement
whiteButton.addEventListener('click', () => {
  color = 'white'
})
const resetButton = document.getElementById('resetButton') as HTMLButtonElement
resetButton.addEventListener('click', () => {
  reset()
})

canvas.addEventListener('mousemove', (e) => {
  if (e.buttons) {
    prevX = currX
    prevY = currY
    currX = e.clientX - canvas.getBoundingClientRect().left
    currY = e.clientY - canvas.getBoundingClientRect().top
    draw()

    socket.emit('draw', [prevX, prevY, currX, currY, color])
  }
})
canvas.addEventListener('mousedown', (e) => {
  currX = e.clientX - canvas.getBoundingClientRect().left
  currY = e.clientY - canvas.getBoundingClientRect().top
})
canvas.addEventListener('mouseenter', (e) => {
  currX = e.clientX - canvas.getBoundingClientRect().left
  currY = e.clientY - canvas.getBoundingClientRect().top
})

function draw() {
  ctx.beginPath()
  ctx.moveTo(prevX, prevY)
  ctx.lineTo(currX, currY)
  ctx.strokeStyle = color
  ctx.lineWidth = thickness
  ctx.stroke()
  ctx.closePath()
}

function reset() {
  ctx.clearRect(0, 0, canvas.width, canvas.height)
}

./src/client/webpack.dev.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
const path = require('path')

module.exports = {
  mode: 'development',
  devtool: 'eval',
  devServer: {
    static: {
      directory: path.join(__dirname, '../../dist/client')
    },
    hot: true,
    proxy: [
      {
        context: ['/socket.io'],
        target: 'http://localhost:3000',
        ws: true
      }
    ]
  },
  entry: {
    rng: path.resolve(__dirname, './rng.ts'),
    colabPainter: path.resolve(__dirname, './colabPainter.ts')
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js']
  },
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, '../../dist/client')
  }
}

./dist/client/rng.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>
      Socket.IO TypeScript Tutorials by Sean Bradley : https://sbcode.net/tssock/
    </title>
    <style>
      body {
        font-size: 4vw;
      }
    </style>
  </head>

  <body>
    <script type="module" src="rng.bundle.js"></script>
  </body>
</html>

./dist/client/colabPainter.html

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>
      Colab Painter : Socket.IO TypeScript Tutorials by Sean Bradley :
      https://sbcode.net/tssock/
    </title>
    <style>
      body {
        overflow: hidden;
        margin: 0px;
      }

      #canvas {
        width: 100%;
        height: 100%;
      }

      #greenButton {
        background: green;
        position: absolute;
        left: 0px;
        width: 80px;
        height: 40px;
      }

      #blueButton {
        background: blue;
        position: absolute;
        left: 80px;
        width: 80px;
        height: 40px;
      }

      #redButton {
        background: red;
        position: absolute;
        left: 160px;
        width: 80px;
        height: 40px;
      }

      #yellowButton {
        background: yellow;
        position: absolute;
        left: 240px;
        width: 80px;
        height: 40px;
      }

      #orangeButton {
        background: orange;
        position: absolute;
        left: 320px;
        width: 80px;
        height: 40px;
      }

      #blackButton {
        background: black;
        position: absolute;
        left: 400px;
        width: 80px;
        height: 40px;
      }

      #whiteButton {
        background: white;
        position: absolute;
        left: 480px;
        width: 78px;
        height: 38px;
        border: 1px solid black;
      }

      #resetButton {
        position: absolute;
        left: 560px;
        width: 78px;
        height: 40px;
        border-radius: 0;
      }
    </style>
  </head>
  <body>
    <canvas
      id="canvas"
      width="628"
      height="400"
      style="position: absolute; top: 40px; border: 5px solid"
    ></canvas>
    <div id="greenButton"></div>
    <div id="blueButton"></div>
    <div id="redButton"></div>
    <div id="yellowButton"></div>
    <div id="orangeButton"></div>
    <div id="blackButton"></div>
    <div id="whiteButton"></div>
    <input id="resetButton" type="button" value="Reset" />
    <script type="module" src="colabPainter.bundle.js"></script>
  </body>
</html>