geckos.io

repository·master·Indexed 23 days ago

https://github.com/geckosio/geckos.io

A real-time client/server communication library for HTML5 multiplayer games using WebRTC and UDP in Node.js to provide lower latency than TCP-based WebSockets. It consists of @geckos.io/client, @geckos.io/server, and a shared @geckos.io/common module. Features include support for rooms, authorization via HTTP headers, connection buffering management to prevent latency spikes, and customizable port ranges for WebRTC connections.

Tokens
9.2K
Snippets
19
Records
54
Agent score
80%

What's inside geckos.io

  1. Understand the role of @geckos.io/common

    master
    The @geckos.io/common package is a shared module used by both the @geckos.io/client and @geckos.io/server packages. It contains the shared logic, types, and utilities required to facilitate real-time communication between the client and the server in a geckos.io application.
  2. Manage connection buffering and dropped messages

    master

    To prevent latency spikes in real-time games, geckos.io uses autoManageBuffering (enabled by default). When enabled, the library prefers dropping messages instead of queuing them if the connection cannot keep up.

    Note: Messages sent with { reliable: true } will still be queued and not dropped.

    To monitor network congestion and adjust your game's send rate, use the channel.onDrop method.

  3. Basic client-server usage

    master

    Geckos.io provides a real-time communication layer. The server listens on a port and handles connections, while the client connects to the server to emit and listen for events.

    Server Setup:

    • Use geckos() to initialize the server.
    • Call .listen(port) to start listening (default port is 9208).
    • Use .onConnection(callback) to handle new client channels.
    • Use io.room(roomId).emit(...) to broadcast to specific rooms.

    Client Setup:

    • Use geckos({ port }) to initialize the client.
    • Use .onConnect(callback) to handle connection status.
    • Use .on(event, callback) to listen for messages.
    • Use .emit(event, data) to send messages.
    // client.js
    import geckos from '@geckos.io/client'
    
    const channel = geckos({ port: 3000 })
    
    channel.onConnect(error => {
      if (error) {
        console.error(error.message)
        return
      }
    
      channel.on('chat message', data => {
        console.log(`You got the message ${data}`)
      })
    
      channel.emit('chat message', 'a short message sent to the server')
    })
    
    // server.js
    import geckos from '@geckos.io/server'
    
    const io = geckos()
    
    io.listen(3000)
    
    io.onConnection(channel => {
      channel.onDisconnect(() => {
        console.log(`${channel.id} got disconnected`)
      })
    
      channel.on('chat message', data => {
        console.log(`got ${data} from "chat message"`)
        io.room(channel.roomId).emit('chat message', data)
      })
    })
  4. Implement Authorization and Authentication

    master

    Geckos.io supports authentication via HTTP headers and server-side validation.

    Client Side: Pass an authorization string in the geckos() configuration. This string is sent as an Authorization request header.

    Server Side: Provide an authorization async function in the geckos() configuration.

    • The function receives auth (the header string), the request, and the response.
    • Return an object: This object will be attached to channel.userData on the client.
    • Return true: Authorizes the connection without adding userData.
    • Return false: Responds with a 401 Unauthorized error.
    • Return a number: Responds with that specific HTTP status code (e.g., 400, 404).

    Note: If the client and server are on different domains, you must set cors: { allowAuthorization: true } on the server.

    // client.ts
    const username = 'Yannick'
    const password = '12E45'
    const auth = `${username} ${password}`
    const channel = geckos({ authorization: auth })
    
    channel.onConnect(error => {
      if (error) {
        console.error('Status: ', error.status)
        return
      }
      console.log(channel.userData) // Access authenticated data
    })
    
    // server.ts
    const io: GeckosServer = geckos({
      authorization: async (auth, request, response) => {
        const token = auth?.split(' ')
        const username = token?.[0]
        const password = token?.[1]
    
        const user = await database.getByName(username)
    
        if (user?.username === username && user?.password === password)
          return { username: user.username, level: user.level, points: user.points }
    
        return false
      },
      cors: { allowAuthorization: true }
    })
  5. Develop geckos.io from source

    master

    If you are contributing to the geckos.io repository, follow these steps to set up your local development environment:

    1. Install dependencies: npm install
    2. Run tests: npm test
    3. Start the development server: npm run dev
    npm install
    npm test
    npm run dev
  6. Install geckos.io

    master

    To use geckos.io in your project, install both the client and server packages via npm.

    Note for Version 3: Version 3 is based on node-datachannel, supports ESM, and requires Node.js >=16.

    npm install @geckos.io/client @geckos.io/server
  7. Deploy geckos.io and configure network ports

    master

    When deploying geckos.io, your server must be able to forward traffic on two types of ports:

    1. TCP Port: Used for peer signaling (e.g., 9208/tcp or your custom configured port).
    2. UDP Port Range: Used for the actual WebRTC peer connections. You must open a range such as 1025-65535/udp to your application.
  8. Integrate geckos.io with Node.js HTTP or Express Servers

    master

    You can run geckos.io as a standalone server or attach it to an existing Node.js HTTP or Express server. When attaching, ensure the client connects to the same port used by the HTTP server for signaling.

    Standalone:

    import geckos from '@geckos.io/server'
    const io = geckos()
    io.listen(3000)

    Node.js HTTP Server:

    import geckos from '@geckos.io/server'
    import http from 'http'
    
    const server = http.createServer()
    const io = geckos()
    
    io.addServer(server)
    server.listen(3000)

    Express:

    import geckos from '@geckos.io/server'
    import http from 'http'
    import express from 'express'
    
    const app = express()
    const server = http.createServer(app)
    const io = geckos()
    
    io.addServer(server)
    server.listen(3000)
    // Express Example
    import geckos from '@geckos.io/server'
    import http from 'http'
    import express from 'express'
    
    const app = express()
    const server = http.createServer(app)
    const io = geckos()
    
    io.addServer(server)
    io.onConnection( channel => { ... })
    server.listen(3000)
  9. Configure ICE Servers for Production

    master

    Geckos.io provides default ICE servers for testing, but for production, you should use your own STUN and TURN servers to ensure connectivity across different network environments.

    Local Development: Pass an empty array to iceServers to avoid unnecessary external requests.

    Production: Provide your own array of RTCIceServer objects.

    import geckos, { iceServers } from '@geckos.io/server'
    
    // Use null/empty for local, or the provided iceServers for testing/production
    const io = geckos({ iceServers: null, TESTING_LOCALLY ? [] : iceServers })
    import geckos, { iceServers } from '@geckos.io/server'
    
    const io = geckos({ iceServers: null, TESTING_LOCALLY ? [] : iceServers })
  10. Configure server multiplexing and port ranges

    master

    You can customize how the server manages ports and connections during initialization.

    • Multiplexing: When multiplex: true (default), the first available port in the range is used for all connections. If set to false, a new port is assigned for each connection.
    • Custom Port Range: Define a specific range of ports for WebRTC connections using the portRange option.
    // Multiplexing
    const io = geckos({
      multiplex: true // default
    })
    
    // Custom Port Range
    const io = geckos({
      portRange: {
        min: 10000,
        max: 20000
      }
    })