toa-net v1.5.4
Toa-net
JSON-RPC 2.0 client/server over TCP net.
Features
- Use JSON-RPC 2.0 Specification as RPC protocol.
- Use RESP (Redis Serialization Protocol) or MsgP (Byte Message Protocol) as message protocol.
- Use JSON Web Signatures as authentication protocol.
- Implemented ES6 Iterable protocol.
Implementations
- snapper-core Teambition push messaging service, based on redis.
- snapper-producer Snapper producer client for node.js.
Examples
Simple
const net = require('toa-net')
const auth = new net.Auth('secretxxx')
const server = new net.Server(function (socket) {
socket.on('message', (message) => {
console.log(message)
// { payload: { jsonrpc: '2.0', method: 'hello', params: [ 1 ] },
// type: 'notification' }
// ...
if (message.type === 'request') {
// echo request
socket.success(message.payload.id, message.payload.params)
}
})
})
server.listen(8000)
// Enable authentication for server
server.getAuthenticator = function () {
return (signature) => auth.verify(signature)
}
const client = new net.Client()
// Enable authentication for client
client.getSignature = function () {
return auth.sign({id: 'clientIdxxx'})
}
client.connect(8000)
client.notification('hello', [1])
client.notification('hello', [2])
client.notification('hello', [3])
client.request('echo', {a: 4})((err, res) => {
console.log(err, res) // null { a: 4 }
client.destroy()
server.close()
})Iterator
Socket is async iterable object!
const thunk = require('thunks')()
const net = require('toa-net')
// 创建服务器
const server = new net.Server(function (socket) {
thunk(function * () {
// 高能!!!异步迭代 socket 接收的数据,socket 关闭后迭代结束
for (let value of socket) {
let message = yield value
console.log(message)
// { payload: { jsonrpc: '2.0', method: 'hello', params: [ 1 ] },
// type: 'notification' }
// ...
if (message.type === 'request') {
// respond to the request
socket.success(message.payload.id, message.payload.params)
}
}
})((err) => {
console.log(err)
process.exit(0)
})
})
server.listen(8000)
// 创建客户端
const client = new net.Client().connect(8000)
// 向服务器发出 notification
client.notification('hello', [1])
client.notification('hello', [2])
client.notification('hello', [3])
// 向服务器发出 RPC 请求,服务器将 echo 请求数据
client.request('echo', {a: 4})((err, res) => {
console.log(err, res) // null { a: 4 }
client.destroy()
server.close()
})Bench https://github.com/toajs/toa-net/tree/master/bench
gRPC vs axon vs toa-net, 5000000 Ping/Pong messages, 1 TCP connection, Node.js v6
- gRPC, no-delay: 1000 cocurrency, 1240066 ms, 4032.04 ops
- axon, no-delay: 1000 cocurrency, 204176 ms, 148888.89 kb, 24488.68 ops
- toa-net, no-delay: 1000 cocurrency, 73789 ms, 263272.57 kb, 67760.78 ops
100000 Ping/Pong messages
- local -> local, no-delay: 1000 cocurrency, 3180ms, 31446 ops
- local -> local, delay 1000ms: 1000 cocurrency, 100590ms, 994 ops
- local -> local, delay 1000ms: 5000 cocurrency, 20869ms, 4791 ops
- local -> local, delay 1000ms: 10000 cocurrency, 11074ms, 9030 ops
10000 simple messages, 1000 cocurrency
// message
{
name: 'abcdefghijklmnopqrst',
email: 'abcdefghijklmnopqrst@test.com',
location: 'zhangjiang, shanghai, china'
}- aliyun -> aws: 264321ms, 37 ops, 4.61 kb/s
- aws -> aliyun: 82129ms, 121 ops, 14.84 kb/s
- aliyun -> proxy_cn -> fiber -> proxy_us -> aws: 8056ms, 1241 ops, 151.30 kb/s
Install
npm install toa-netAPI
const toaNet = require('toa-net')Class toaNet.Server
new toaNet.Server(connectionListener)
Create RPC server.
const server = new net.Server(function (socket) {
socket.on('message', (message) => {
console.log(message)
})
})
server.listen(8000)connectionListener: Required, Type:Function.
Event: 'close'
Event: 'error'
Event: 'listening'
server.getAuthenticator()
Abstract method. Should be overridden to enable authentication.
Default:
server.getAuthenticator = function () {
return null // Disable authentication
}Enable authentication:
const auth = new net.Auth('secretxxx')
server.getAuthenticator = function () {
return (signature) => auth.verify(signature)
}server.address()
Returns the bound address.
server.connections: RingPool
server.connections.length
Returns the number of concurrent connections on the server.
server.connections.next()
Return a socket in turn. Return null if no socket available.
server.close(callback)
Closes the server.
server.listen(...)
Same as node.js server.listen
Class toaNet.Client
Event: 'close'
Event: 'connect'
Event: 'auth'
Event: 'message'
Event: 'drain'
Event: 'end'
Event: 'error'
Event: 'timeout'
new toaNet.Client(options)
Creates RPC client.
const client = new net.Client().connect(8000)options.retryDelay: Optional, Type:Number, Default:500ms. Sets time interval for reconnection.options.maxAttempts: Optional, Type:Number, Default:50. Sets max attempts for reconnection.options.tcpTimeout: Optional, Type:Number, Default:0. Sets the socket to timeout after timeout milliseconds of inactivity on the socket.options.tcpNoDelay: Optional, Type:Boolean, Default:true. Disables the Nagle algorithm.options.tcpKeepAlive: Optional, Type:Boolean, Default:true. Enable/disable keep-alive functionality, and optionally set the initial delay before the first keepalive probe is sent on an idle socket.
client.connect(...)
Same as node.js socket.connect
client.connect('tcp://127.0.0.1:33333')client.getSignature()
Abstract method. Should be overridden to enable authentication.
Default:
client.getSignature = function () {
return '' // Disable authentication
}Enable authentication:
const auth = new net.Auth('secretxxx')
client.getSignature = function () {
return auth.sign({id: 'example'})
}client.request(method, params)
Creates a JSON-RPC 2.0 request to another side. Returns thunk function.
client.request('echo', {name: 'zensh'})((err, res) => {
console.log(err, res)
})method: Required, Type:String.params: Optional, Type:Object|Array.
client.notification(method, params)
Creates a JSON-RPC 2.0 notification to another side. No return.
client.notification('hello', {name: 'zensh'})method: Required, Type:String.params: Optional, Type:Object|Array.
client.success(id, result)
Respond success result to the request of id. No return.
client.success(1, 'OK')id: Required, Type:String|Integer, the request'sid.result: Required, Type:Mixed.
client.error(id, error)
Respond error to the request of id. No return.
client.error(1, new Error('some error'))id: Required, Type:String|Integer, the request'sid.error: Required, Type:Error.
client.createError(error, code, data)
client.createError(message, code, data)
client.createError(code, data)
client.throw(error, code, data)
client.throw(message, code, data)
client.throw(code, data)
client.handleJsonRpc(jsonRpc, handleFn)
client.address()
client.destroy()
client[Symbol.iterator]()
Class toaNet.Auth
new toaNet.Auth(options)
Creates auth object for Server and Client.
const auth = new net.Auth({
expiresIn: 3600,
secrets: ['secretxxx1', 'secretxxx2', 'secretxxx3']
})options.secrets: Required, Type:Stringor aArrayof string.options.expiresIn: Optional, Type:Number, Default:3600seconds.options.algorithm: Optional, Type:String, Default:'HS256'.
auth.sign(payload)
Returns a new signature string.
let signature = auth.sign({id: 'xxxxxxId'})auth.verify(signature)
Verify the signature, return payload object if success, or throw a error.
let session = auth.verify(signature)auth.decode(signature)
Try decode the signature, return payload object if success, or null.
let signature = auth.decode(signature)Advance API
Class toaNet.Resp
Class toaNet.Queue
Class toaNet.Socket
Class toaNet.RingPool
Class toaNet.RPCCommand
toaNet.jsonrpc
License
Toa-net is licensed under the MIT license. Copyright © 2016-2018 Toajs.
8 years ago
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago