WebSocket Server and Client implementation of the JSON RPC-2 spec
npm install wss-rpc2WebSocket Server and Client implementation of the JSON RPC2 spec.\
Powered by ws.
!npm
!NPM

#### Basic functionality, according to the spec:
- Method call: client -> server (request/response)
- Notifications: client -> server (notification)
#### Extended functionality:
- Events: server -> client (to all / to some / to a single client)
- Reconnect and keep alive
- Stateful client connection
- The client works in both node and browser
Installation:
``shell`
npm i wss-rpc2
Backend / Server:
`typescript
import { RPCServer, RPCEvent } from 'wss-rpc2'
const server = new RPCServer({ port: 3000 })
server.registerMethod('multiply', (params) => {
return params[0] * params[1]
})
`
Frontend / Client:
`typescript
import { RPCClient } from 'wss-rpc2'
const client = new RPCClient('ws://localhost:3000')
const result = await client.call('multiply', [3, 5])
`
See more examples.
Parameters:
- options: IRPCServerOptionswss?: ws.WebSocketServer
- - existing WebSocketServer (ws) instancekeepAlive?: number
- - ping clients every N ms (default: 300000 // 5 min)stateFactory?: () => State
- - initial state factory of the connected client ...ServerOptions
- (see ws library)
---
Parameters:
- name: string - name of the RPC methodmethod: IRPCMethod
- - RPC method function, see types
---
Call a method explicitly
Parameters:
- name: string - name of the RPC methodparams: IRPCParams
- - params of the RPC method
---
Returns active connection instances.
---
Closes all active client's connections and stops the server.
----
Subscribe a listener to the event. Returns unsubscribe function.
#### RPCServer Events:
- listening (params: empty) - on server startconnect (params: RPCConnection)
- - on client connectdisconnect (params: RPCConnection)
- - on client disconnectrequest (params: RPCRequest)
- - on after request receivedresponse (params: RPCResponse)
- - on before response senterror (params: Error | unknown)
- - on server errorclose (params: empty)
- - on server stop
Parameters:
- address: string - URL of the RPCServeroptions: IRPCClientOptions
- autoConnect?: boolean
- - if false, then use client.connect() (default: true)reconnectIntervals?: number[]
- - reconnect intervals sequence. Example: [1000, 1500, 2000] will wait betweenreconnectLimit
reconnect: 1000ms, 1500ms, 2000ms, ..., 2000ms, until is reached (default: [1000] - every 1000 ms)reconnectLimit?: number
- - 0 - unlimited, -1 - disabled (default: 1000)requestTimeout?: number
- - request timeout (default: 10000)
---
Client connection state:
- init - before connect() has been calledconnecting
- - connection or reconnection is in processconnected
- - active connection statestopped
- - if disconnect() has been called or reconnectLimit is reached
---
Connection promise.
However, it is not necessary to wait for a connection,
because requests will be queued up until the connection is established.
`typescript`
const client = new RPCClient()
await client.connected
// connected!
---
Manual connect, if autoConnect = false
`typescript`
const client = new RPCClient({ autoConnect: false })
await client.connect()
// connected!
---
Disconnects and stops a reconnect-observer.
---
Calls the method and waits for a response.
---
Notifies the server without waiting for a response.
---
Subscribe a listener to the event. Returns unsubscribe function.
#### RPCClient Events:
- connect (params: empty) - on connectdisconnect (params: empty)
- - on disconnecterror (params: Error | unknown)
- - on errorrequest (params: IRPCRequestObject)
- - on before request sentresponse (params: IRPCResponseObject)
- - on response receivedevent (params: RPCEvent)
- - on server event received
Connection identifier
---
Browser WebSocket object (isomorphic-ws is used for the node client)
---
Domain state of the connection, if defined by IRPCServerOptions.stateFactory (and State generic for TS).
---
Last client's activity timestamp
---
Emit an event to the client. Example:
`typescript`
const event = new RPCEvent({ event: 'hello', params: {} })
server.getConnections().forEach(connection => {
connection.emit(event, e => console.error(e))
})
`typescript`
interface IRPCServerOptions extends ws.ServerOptions {
wss?: WebSocketServer
keepAlive?: number
stateFactory?: () => State
}
`typescript`
interface IRPCClientOptions {
autoConnect?: boolean
reconnectIntervals?: number[]
reconnectLimit?: number
requestTimeout?: number
}
`typescript`
type IRPCParams = { [key: string]: unknown } | unknown[]`typescript`
type IRPCMethod
= (params: Req, connection: RPCConnection
`typescript`
interface IRPCRequestObject {
jsonrpc: '2.0'
id?: string | number
method: string
params?: IRPCParams
}
`typescript`
interface IRPCResponseObject {
jsonrpc: '2.0'
id: string | number | null
result?: any
error?: IRPCError
}
`typescript`
interface IRPCError {
code: number
message: string
data?: unknown
}
Typescript support provides several useful features for typing request, responses and connection state.
`typescript
import { RPCServer } from 'wss-rpc2'
const server = new RPCServer
stateFactory: () => ({ authorized: false })
})
server.registerMethod
const user = await auth(params)
if (user) {
connection.state.authorized = true
connection.state.email = user.email
connection.state.id = user.id
}
return user
})
interface IAppUserState {
authorized: boolean
email?: string
id?: string
}
interface IRpcLogin {
request: {
login: string
password: string
}
response: {
user?: {
id: string
email: string
}
}
}
`
`typescript
import { RPCClient } from 'wss-rpc2'
const client = new RPCClient(url)
const { error, result } = await client.call<{ user: IUser | null }>('login', { email, password })
console.log(result?.user?.id)
``
To be done\
Also see tests