You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
2.2 KiB

const uuid = require('uuid').v4
const { Message } = require('../shared')
const { Injectable } = require('flitter-di')
class Socket extends Injectable {
static get services() {
return [...super.services, 'app', 'output']
}
messages = []
constructor(socket) {
super()
this.socket = socket
this.uuid = uuid()
this.session = {}
this.socket.on('message', msg => this.on_message(msg))
}
ping() {
this.send(Message.route('meta.ping').expect_response())
}
send(message) {
this.output.debug(message)
if ( typeof message === 'string' ) {
this.socket.send(message)
return
}
if ( message.needs_response ) {
this.messages.push(message)
}
const serial = message.serialize()
this.socket.send(serial)
}
async on_message(msg) {
this.output.debug(msg)
const message = new Message(msg)
const response = new Message()
message.socket = this
if ( message.is_response() ) {
// Try to find the message that sent the request
const request = this.messages.find(x => x.uuid() === message.response_to())
if ( request ) {
await request._response_callback(message)
request.has_response = true;
} else {
this.send(
response.response_to(message.uuid())
.error(Errors.InvalidReplyUUID)
)
}
this.messages = this.messages.filter(x => !x.has_response)
} else {
if ( this.needs_auth(message.route()) && !this.session.is_auth ) {
return this.send(response.error(Errors.NodePermissionFail))
}
let handler;
try {
handler = require(`./routes/${message.route()}`)
} catch (e) {}
if ( !handler ) {
return this.send(response.error(Errors.InvalidMessageRoute))
}
await handler(message, this.app.di().container.proxy())
}
}
needs_auth(route) {
return route.startsWith('fs.') || route.startsWith('stream.')
}
}
module.exports = exports = Socket