src/plugin/dgram.js
- import dgram from 'dgram'
-
- import Plugin from './plugin'
-
- /**
- * Status flags
- * @private
- */
- const STATUS = {
- IS_NOT_INITIALIZED: -1,
- IS_CONNECTING: 0,
- IS_OPEN: 1,
- IS_CLOSING: 2,
- IS_CLOSED: 3,
- }
-
- /**
- * Default options for open method
- * @private
- */
- const defaultOpenOptions = {
- host: 'localhost',
- port: 41234,
- exclusive: false,
- }
-
- /**
- * Default options for send method
- * @private
- */
- const defaultSendOptions = {
- host: 'localhost',
- port: 41235,
- }
-
- /**
- * Default options
- * @private
- */
- const defaultOptions = {
- type: 'udp4',
- open: defaultOpenOptions,
- send: defaultSendOptions,
- }
-
- /**
- * Helper method to merge nested objects
- * @private
- */
- function mergeOptions(base, custom) {
- return {
- ...defaultOptions,
- ...base,
- ...custom,
- open: { ...defaultOptions.open, ...base.open, ...custom.open },
- send: { ...defaultOptions.send, ...base.send, ...custom.send },
- }
- }
-
- /**
- * OSC plugin for simple OSC messaging via udp client
- * and udp server
- */
- export default class DatagramPlugin extends Plugin {
- /**
- * Create an OSC Plugin instance with given options. Defaults to
- * localhost:41234 for server and localhost:41235 for client messaging
- * @param {object} [options] Custom options
- * @param {string} [options.type='udp4'] 'udp4' or 'udp6'
- * @param {string} [options.open.host='localhost'] Hostname of udp server to bind to
- * @param {number} [options.open.port=41234] Port of udp server to bind to
- * @param {boolean} [options.open.exclusive=false] Exclusive flag
- * @param {string} [options.send.host='localhost'] Hostname of udp client for messaging
- * @param {number} [options.send.port=41235] Port of udp client for messaging
- *
- * @example
- * const plugin = new OSC.DatagramPlugin({ send: { port: 9912 } })
- * const osc = new OSC({ plugin: plugin })
- */
- constructor(options = {}) {
- super()
-
- // `dgram` gets replaced with an undefined value in builds targeting
- // browser environments
- if (!dgram) {
- throw new Error('DatagramPlugin can not be used in browser context')
- }
-
- /**
- * @type {object} options
- * @private
- */
- this.options = mergeOptions({}, options)
-
- /**
- * @type {object} socket
- * @private
- */
- this.socket = dgram.createSocket(this.options.type)
- /**
- * @type {number} socketStatus
- * @private
- */
- this.socketStatus = STATUS.IS_NOT_INITIALIZED
-
- // register events
- this.socket.on('message', (message, rinfo) => {
- this.notify(message, rinfo)
- })
-
- this.socket.on('error', (error) => {
- this.notify('error', error)
- })
-
- /**
- * @type {function} notify
- * @private
- */
- this.notify = () => {}
- }
-
- /**
- * Internal method to hook into osc library's
- * EventHandler notify method
- * @param {function} fn Notify callback
- * @private
- */
- registerNotify(fn) {
- this.notify = fn
- }
-
- /**
- * Returns the current status of the connection
- * @return {number} Status ID
- */
- status() {
- return this.socketStatus
- }
-
- /**
- * Bind a udp socket to a hostname and port
- * @param {object} [customOptions] Custom options
- * @param {string} [customOptions.host='localhost'] Hostname of udp server to bind to
- * @param {number} [customOptions.port=41234] Port of udp server to bind to
- * @param {boolean} [customOptions.exclusive=false] Exclusive flag
- */
- open(customOptions = {}) {
- const options = { ...this.options.open, ...customOptions }
- const { port, exclusive } = options
-
- this.socketStatus = STATUS.IS_CONNECTING
-
- this.socket.bind({
- address: options.host,
- port,
- exclusive,
- }, () => {
- this.socketStatus = STATUS.IS_OPEN
- this.notify('open')
- })
- }
-
- /**
- * Close udp socket
- */
- close() {
- this.socketStatus = STATUS.IS_CLOSING
-
- this.socket.close(() => {
- this.socketStatus = STATUS.IS_CLOSED
- this.notify('close')
- })
- }
-
- /**
- * Send an OSC Packet, Bundle or Message. Use options here for
- * custom port and hostname, otherwise the global options will
- * be taken
- * @param {Uint8Array} binary Binary representation of OSC Packet
- * @param {object} [customOptions] Custom options for udp socket
- * @param {string} [customOptions.host] Hostname of udp client
- * @param {number} [customOptions.port] Port of udp client
- */
- send(binary, customOptions = {}) {
- const options = { ...this.options.send, ...customOptions }
- const { port, host } = options
-
- this.socket.send(Buffer.from(binary), 0, binary.byteLength, port, host)
- }
- }