@rplan/socketio-client
v3.5.1
Published
Socket.io client for Allex
Downloads
1,143
Maintainers
Keywords
Readme
Responsible: #A-Team
allex-socketio-client
:zap: Socket.io client for Allex
Features
This is a typed client wrapper around socket.io-client
. It provides the following features:
- A React hook
useRealTimeUpdates
that enables components to receive real time updates from the server. - It debounces incoming sequential events for a configurable time, so that less re-renders are needed in case of an event burst.
- It manages multiple subscriptions, so that if several different components subscribe to the same entity, a single subscription request is sent to the server. Also, it handles unsubscriptions automatically, and only unsubscribes when no component is listening for changes for a particular entity.
- When the component using this hook is unmounted, this library takes care of unsubscribing from the entities automatically. Apart from that, the library also provides a function that can be used to manually unsubscribe if required.
- It provide audience events, which is a way to communicate what users are also listening for updates to the same entities that the client is subscribed to. Audience events are triggered everytime another user subscribe or unsubscribe to an entity. Audience events payload will provide an array of user ids, so you will have to make an additional request if you need extra data from these users.
How it Works
A client can subscribe to updates from any entity. However, for particular types of entities you might be interested in updates to their children entities as well. For example, you may like to subscribe to a project entity, and get updates such as a new task or a new milestone created within that project. This is supported by specifying that you want to subscribe to this entity as a project.
Currently, special entity types supported are project
and principal
as shown below.
Installation
This library is used as a peer dependency provided by rplan-webclient
, so you should install it as both a peer dependecy and a dev dependency (so your tests can execute without any issues).
npm install -D @rplan/socketio-client # to install as devDependency
npm install -P @rplan/socketio-client # to install as a peerDependecy
Usage
Subscribing to Entities
import { useRealTimeUpdates, EntityType } from '@rplan/socketio-client'
const subscribedEntities = [{
entityId: '...', // `entityId` is mandatory
entityType: EntityType.PROJECT // `entityType` is optional
}]
// The following handlers will be invoked whenever there is an update for a given entity type.
const handlers = {
onEntityUpdates: () => { ... }, // optional
onProjectUpdates: () => { ... }, // optional
onPrincipalUpdates: () => { ... }, // optional
onAudienceUpdates: () => { ... }, // optional
}
const options = { // `options` is optional. Below are the default values
debounceIntervalMillis: 1000 // Time interval to aggregate events before invoking the handlers
}
const unsubscribe = useRealTimeUpdates(subscribedEntities, handlers, options)
Unsubscribing from Entities
unsubscribe([
{ entityId: '...' }, // No need to provide `entityType` for unsubscriptions.
{ entityId: '...' },
])
Updates
For principal
and project
updates, you wil receive a nested structure, which can be difficult to navigate. For that reason, we provide a .traverse
function that can be used as follows:
For project
subscriptions
import { useRealTimeUpdates, EntityType } from '@rplan/socketio-client'
const subscribedEntities = [{
entityId: 'projectId',
entityType: EntityType.PROJECT
}]
useRealTimeUpdates(subscribedEntities, {
onProjectUpdates: (updates) => {
updates.traverse(({ projectId, meta, payload }) => {
// `projectId` is the project id of the change
// `meta` contains meta information about the changed entity
// `payload` the change set for given entity
})
},
})
For principal
subscriptions
import { useRealTimeUpdates, EntityType } from '@rplan/socketio-client'
const subscribedEntities = [{
entityId: 'principalId', // can be the id of a `user` or an `organisation`
entityType: EntityType.PRINCIPAL
}]
useRealTimeUpdates(subscribedEntities, {
onPrincipalUpdates: (updates) => {
updates.traverse(({ principalId, meta, payload }) => {
// `principalId` is the principal id of the change
// `meta` contains meta information about the changed entity
// `payload` the change set for given entity
})
},
})
Special Entity Type Subscriptions
You can subscribe to updates for the children of an entity (and the entity inclusive). Currently this is possible for a project or a principal. A principal can be either a user or an organisation.
Project children are:
- Task
- Sub Task
- Milestone
User (Principal) children are:
- Project
- Standalone Task
Organisation (Principal) children are:
- Project
Heads Up
- Functions passed to
useRealTimeUpdates
need to be used enclosed within auseCallback
to prevent unnecessary re-renders. Here is an example from mytasks-overview-webclient. - It is considered a good practice to NOT use the contents of the payload to update the UI, this is because client may loose some events in case of a temporary disconnection and this would result in an inconsistent UI. It is recommended, to instead, make a new request to refresh the full state of the entity shown in the UI.
- If the user lacks permissions on one of the requested entities, the server will return a generic
404
error instead of a403
, this is so that we do not disclose the existence of an entity on our system with that specificentityId
.