npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@gigasource/socket.io-p2p-plugin

v2.0.0

Published

# 1. Overview This library consists of 2 components: - P2P Server Plugin (src/p2p-server-plugin.js): plugin for [socket.io](https://www.npmjs.com/package/socket.io) lib - P2P Client Plugin (src/p2p-client-plugin.js): plugin for [socket.io-client](http

Downloads

50

Readme

socket.io-p2p-plugin

1. Overview

This library consists of 2 components:

  • P2P Server Plugin (src/p2p-server-plugin.js): plugin for socket.io lib
  • P2P Client Plugin (src/p2p-client-plugin.js): plugin for socket.io-client lib

In each component, the code is split into 4 APIs:

  • Core: consists of common functions for other APIs and functions related to Socket.IO's basic features such as room control (joinRoom, leaveRoom, emitRoom).
  • Message: extended functions for Socket.IO. This API focuses on sending messages from clients to clients without having to know the details on Socket.IO server.
  • Stream: extended functions for Socket.IO. This API focuses on interacting with NodeJS Stream API, sending & receiving data between clients using streams.
  • Service: extended functions for Socket.IO. This API allows server & clients to become services to provide/consume socket-based APIs & create subscriber/publisher relationship to monitor data changes.

Glossary

  • Server: Socket.IO server
  • Client: Socket.IO clients
  • Source client: the client that initially sends data
  • Target client: the client that will receive data from source client

API details will be explained with this structure:

  • Function explanation - You should read this and read the code simultaneously (functions not listed are self-explanatory)
  • API requirements

2. P2P Server Plugin

The server must be started before client plugin can be used and before clients can connect to the server.

Code example to start server:

const http = require('http');
const socketIO = require('socket.io');
const p2pServerPlugin = require('../src/p2p-server-plugin');

const httpServer = http.createServer((req, res) => res.end()).listen(9000);

const io = socketIO.listen(httpServer, {}); // see https://socket.io/docs/server-api/#new-Server-httpServer-options for server options

const server = p2pServerPlugin(io);

2.1 Server Core API

2.1.1 Function explanation:

  • addClient/removeClient: add/remove from the clientMap to know which client is connected to the server. The structure of clientMap is:
{
  clientIdA: 'socketId123', // clientId is set by client, socketId is generated randomly
  clientIdB: 'socketId456',
}
  • getSocketByClientId: use clientId to find socketId, then socketId is used to get Socket object, the Socket object can use Socket.IO functions (emit, on, ...)
  • emitError: logs an error using console.error & at the same time, emit the error to source client, client can listen to this to catch errors
  • createListeners: create the listeners for Socket.IO events:
    • disconnect: remove client from clientMap
    • P2P_EMIT: event used by clients to send data
    • P2P_EMIT_ACKNOWLEDGE: event used by clients to send data with acknowledge function
    • JOIN_ROOM, LEAVE_ROOM: control the joining/leaving room of sockets
    • EMIT_ROOM: emit data to all the sockets in a room

2.1.2 Requirements

  • Connected clients must be added to clientMap
  • Disconnected clients must be removed from clientMap
  • A new socket is created when a client connects to server
  • Every created socket must listen to P2P_EMIT, P2P_EMIT_ACKNOWLEDGE, JOIN_ROOM, LEAVE_ROOM & EMIT_ROOM events
  • clientId is required & must be unique (currently there is no code mechanism to enforce uniqueness, clientId is set by client)

2.2 Server Message API

2.2.1 Function explanation:

  • createListeners: create listener for MULTI_API_ADD_TARGET. Forward this event to target client & handle disconnection from both ends

2.2.2 Requirements:

  • All connected sockets must listen to MULTI_API_ADD_TARGET event
  • When a client disconnects, its targets must be notified with MULTI_API_TARGET_DISCONNECT event. a clientId is sent with MULTI_API_TARGET_DISCONNECT event so target clients can know which specific client disconnected
  • If target client is not registered to server, send error to source client

2.3 Server Stream API

2.3.1 Function explanation:

  • createListeners: the listener for MULTI_API_CREATE_STREAM is mostly similar to the listener for MULTI_API_ADD_TARGET but in MULTI_API_CREATE_STREAM, additional information is included: sourceStreamId, targetStreamId. The streamIds are used for identifying streams since 1 client can create multiple streams

2.3.2 Requirements:

  • All connected sockets must listen to MULTI_API_CREATE_STREAM event
  • Similar to second requirement in 2.2.2 -> for destroying streams related to a client when it disconnects
  • Similar to third requirement in 2.2.2
  • connectionInfo object must be included when MULTI_API_CREATE_STREAM event is sent

2.4 Server Service API

This API is similar to the API in client side, but we want the API usage to be transparent so an intercept mechanism is used to intercept P2P_EMIT & P2P_EMIT_ACKNOWLEDGE events. If server has the requested service and can handle the request, the request will be intercepted, otherwise the request will be passed to client-side service to handle

2.4.1 Function explanation:

  • this.interceptor: used to create the modified listeners for P2P_EMIT & P2P_EMIT_ACKNOWLEDGE events
  • interceptP2pEmit: this function is called if {isService: true} is passed as parameter when server is created. This will create a modified version of original listeners for P2P_EMIT & P2P_EMIT_ACKNOWLEDGE events to intercept the service requests from clients
  • asService: because 1 instance of server can serve as multiple services, this function is used to create APIs as different services
  • initTopicApis: create the listeners that allow clients to subscribe/unsubscribe to topics created by the services on server side

2.4.2 Requirements:

  • 1 server instance can serve as multiple services
  • Clients treat services created by server and services created by other clients alike (as if server is also client)
  • APIs and topics can be created and destroyed
  • Topics created can be subscribed to & messages can be published to topics by server
  • Topics are basically just rooms of Socket.IO (we want to use subscriber/publisher pattern so we use the term 'topic')

3. P2P Client Plugin

Code example to create client:

const clientId = 'clientA'; // this should be unique, currently there is no code mechanism to enforce uniqueness
const socketClient = require('socket.io-client');
const p2pClientPlugin = require("../../../src/p2p-client-plugin");

const rawSocket = socketClient.connect(`http://localhost:9000?clientId=${clientId}`);
const socket = p2pClientPlugin(rawSocket, clientId);

3.1 Client Core API

Core API is pretty simple so explanation is not necessary

3.2 Client Message API

3.2.1 Function explanation

  • addP2pTarget/onAddP2pTarget: most of the time client can not know the id of its peer, onAddP2pTarget is used to get id of peer (refer to examples for usage)
  • onAny/onceAny/offAny: used for creating/removing listeners without clientId filtering
  • from - on/once/off: used for creating/removing listeners with clientId filtering (accept events from specific clients only)
  • emitTo: used to send data to a specific client

3.2.2 Requirements

  • When a target client disconnects, listeners related to that client must be removed from its peers
  • Clients can listen to events from any other clients with 'onAny'
  • Clients can listen to events from chosen clients only with 'from().on'
  • 'once' and 'off' functions must work like basic socket.once & socket.off
  • 'emitTo' must send data to correct target
  • Relationship between clients is n-n

3.3 Client Stream API

3.3.1 Function explanation

  • addP2pStream: used to request connection between clients, if request succeed, a Duplex will be returned
  • onAddP2pStream: used to handle connection request & create a Duplex if request is accepted

3.3.2 Requirements

  • 1 client can have multiple streams but relationship between streams is 1-1
  • Streams with same client must have unique id for identifying purpose
  • The Duplex returned must work like a NodeJS Duplex & must be able to send/receive data through network
  • When client/stream is destroyed, its peer should be cleaned up correctly (remove socket listeners, destroy streams)

3.4 Client Service API

3.4.1 Function explanation

  • initTopicListeners: create listeners for handling topic subscription/unsubscription, only clients created with {isService: true} can handle topic subscription/unsubscription.
  • modifyTopicName: topic name can have conflicts between services so this function add a prefix to identify topics of different services

3.4.2 Requirements

  • Client can use services and be service at the same time
  • 1 instance of client can only be 1 type of service

4. Code examples

Code examples are stored in /example, you can run file exec-file.js in each folder to automatically run files with correct order

5. Roadmap

  • Security
  • Handle duplicated clientId/invalid parameters
  • Timeouts for functions