socket.net
v1.0.31
Published
Node.js websocket enhanced service. Support node.js and browser platform, features: message encrypt(base on 4096 length rsa and symmetric), basic heartbeat, client authorization, directly message, channel message.
Downloads
21
Maintainers
Readme
Socket.Net
Start
More information see in docs.
Server
const http = require("http")
const { WebSocketServerApp } = require("./dist/index");
function boot() {
console.log("server run")
const s = http.createServer()
const sn = new WebSocketServerApp(s)
sn.listen("/socket")
sn.setTokenVerifier((data) => {
console.log(data.id, data.token, data.data)
return true
})
sn.onSession((session) => {
session.onAuthorized(() => {
session.send("服务器无返回测试")
session.send("服务器有返回测试", (payload) => {
console.log(payload)
}, () => {
console.log("服务器有返回测试 2")
})
})
})
sn.onMessage((m, session) => {
session.send(1234, (p) => {
console.log(p)
}, () => {
console.log("done")
})
})
sn.onChannelSessionJoined((id, session) => {
console.log(id, session.id)
sn.channels.assert(id).send("频道进入消息:服务端到客户端")
// sn.channels.get(id).send("服务端发送频道信息")
// sn.channels.get(id).send("1233123213")
// session.channel(id).send(2345, (p) => {
// console.log(p)
// }, () => {
// console.log("done")
// })
})
sn.onChannelSessionExited((id, session) => {
console.log(id, session.id)
sn.channels.assert(id).send("频道退出消息:服务端到客户端")
})
sn.onMessage((message, session) => {
console.log(message.data, message.replay)
if (message.reply) {
message.reply("客户端有返回测试 1")
}
})
s.listen(8090, "0.0.0.0",)
}
boot()
Client
const app = new WebSocketApp({
authorization: {
id: "1",
token: "123",
data: {}
},
heartbeat: {
mode: "client",
duration: 10 * 1000,
}
})
app.onSession((session) => {
session.onMessage((m) => {
console.log(m.data, m.replay)
if (m.reply) {
m.reply("服务器有返回测试 1")
}
})
session.sessions.onMessage((m) => {
console.log(m.data)
if (m.reply) {
m.reply("客户端到客户端有返回测试 1")
}
})
session.onAuthorized((data) => {
session.send("客户端无返回测试")
session.send("客户端有返回测试", (payload) => {
console.log(payload)
}, () => {
console.log("客户端有返回测试 2")
})
session.sessions.to("1").send("客户端到客户端无返回测试")
session.sessions.to("1").send("客户端到客户端有返回测试", (payload) => {
console.log(payload)
}, () => {
console.log("客户端到客户端有返回测试 2")
})
const chan = session.channel("1")
chan.onMessage((m) => {
console.log(m.data)
})
chan.send("频道测试")
chan.join().then(() => {
chan.send("频道测试")
setTimeout(() => {
chan.exit()
}, 1000)
})
})
})
app.conn("ws://127.0.0.1:8090/socket");
Desgin
Model Flow
read
| transport ↑
| encrypt | Use to encrypt and decrypt message. This layer is optional.
| heartbeat | Use to manager the connection.
| authorization | Use to manager the client.
| other | business process.
↓ |
write
On Message
interface message {
type: "client" | "channel"
from: "string"
to: "string"
data: any
/**
* message from server and client: reply will be a function or undefined
* message from channel: reply to channel
*/
reply?: (message: any) => void
}
The arguments of on("message") will replace to interface message
TransportIO Destory
Every Modules implement TransportIO destoryed on transport closed. Module need to implment the destory function to close the emitter, timer and anyother action need to be closed.
class Example {
destroy() { // destroy() is not a required function, so TransportIO interface not declare.
// close everything at here
}
}
const e = new Example(transport, options)
transport.on("close", {
e.destory()
})
Encrypt Layer
Message encrypt layer. Running model same like https.
Flow:
- Client request the public key, and intercept the message writed by other layer until message encrypt module ready, put the message to the message queue.
- Server read the client request and process, return the public key.
- Client read the server's response, generate a symmetric key and store it, use the public key to encrypt the key, write to server after above work done.
- Server read the client message, store the symmetric key, set the isEncrypt variable to true, then return ready status to client.
- Client read the server response, set the isEncrypt variable to ture, trigger the encryped event, then send the messages encrypted in message queue.
Client must be sure is encrypted, otherwise put the message to the message queue
Distributed (Plan)
Distributed processing, let the service run like a tree.
This is just a mind, may be i need to rewrite the business logic, must be set a special node flag to route the message, due to it's no need at present, not implement currently.
Here are the flows:
- Send Message From Child Server
- Child server run a websocket client, and register the client as a router.
- Find target from router if child server could not route the message.
- Parent server process the message as normal flow.
- Send Message From Parent Server
- Child server connect parent server correctly, and register as a router in parent server.
- Find target from multi routers (every router need to maintain a router table, or a table could access a client by this router.) if parent server could not route the message.
- Router if could work transfer the message
- Child server process the message as normal flow.
router need to maintain a table. If router in child server, the table include the parent server which could be arrived. If router in parent server, the logic same with the router in child server but the table only include the child.