node-xyz/xyz-core

View on GitHub
src/Transport/UDP/udp.server.ts

Summary

Maintainability
C
1 day
Test Coverage
import { wrapper } from './../../Util/Util'
import { logger } from './../../Log/Logger'
import { ITransportReceivedMessage } from './../transport.interfaces'
import { CONFIG } from './../../Config/config.global'
import { GenericMiddlewareHandler } from './../../Middleware/generic.middleware.handler'
import { EventEmitter } from 'events'
import * as dgram from 'dgram'
import XYZ from './../../xyz'

export default class UDPServer extends EventEmitter {
  port: number
  xyz: XYZ
  serverId: Object
  server: any
  routes: Object

  constructor (xyz: XYZ, port: number) {
    super()
    this.port = port
    this.xyz = xyz

    /**
     * Each server should have this attribute and pass it to the constructor of
     * xMiddlewareParam object
     */
    this.serverId = {
      type: 'UDP',
      port: port
    }

    this.server = dgram.createSocket('udp4')
    this.routes = {}

    this.server.on('listening', () => {
      let address = this.server.address()
      logger.info(`UDP Server listening on port ${address.address}:${address.port}`)
    })
    .on('message', (message, remote) => {
      let _message = JSON.parse(message.toString())
      for (let route in this.routes) {
        if (_message.xyzPayload.route === `/${route}`) {
          logger.debug(`UDP SERVER @ ${this.port} :: udp message received for /${wrapper('bold', route)} [${JSON.stringify(_message)}]`)

          let xMessage: ITransportReceivedMessage = {
            message: _message,
            response: undefined,
            serverId: this.serverId,
            meta: remote
          }

          this.routes[route].apply(xMessage, 0)
          break
        }
      }
    })
    .bind(port, CONFIG.getSelfConf().host)
  }

  inspect () {
    let ret = `${wrapper('green', wrapper('bold', 'Middlewares'))}:\n`

    for (let route in this.routes) {
      ret += `    ${this.routes[route].inspect()}\n`
    }
    return ret
  }

  inspectJSON () {
    let ret = []
    for (let route in this.routes) ret.push(this.routes[route].inspectJSON())
    return ret
  }

  /**
   * Will close the server. duplicate of `.terminate()`
   */
  close () {
    this.server.close()
  }

  /**
   * Will close the server
   */
  terminate () {
    logger.warn(`UDP SERVER @ ${this.port} :: CLOSING`)
    this.close()
  }

  // will initialize a new route with one default middleware
  // NOTE: this is experimental and there is no support to send sth directly to this
  // from whithin xyz. this is designed mostly for users outside of the system to have
  // a communication way
  registerRoute (prefix, gmwh) {
    let globalUnique = this.xyz.serviceRepository.transport._checkUniqueRoute(prefix)
    if (!globalUnique) {
      logger.error(`UDP Server @ ${this.port} :: route ${prefix} is not unique.`)
      return false
    } else {
      gmwh = gmwh || new GenericMiddlewareHandler(this.xyz, `${prefix}.receive.mw`, prefix)
      this.routes[prefix] = gmwh
      logger.info(`UDP Server @ ${this.port} :: new message route ${wrapper('bold', prefix)} added`)
      return 1
    }
  }

}