refactor to use regular es5 js, no need to make socket a component
This commit is contained in:
parent
dea64e5b7a
commit
cacff29bab
338
UdpSocket.ios.js
338
UdpSocket.ios.js
|
@ -13,14 +13,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react-native')
|
var React = require('react-native')
|
||||||
var {
|
|
||||||
Component
|
|
||||||
} = React
|
|
||||||
|
|
||||||
var mixInEventEmitter = require('mixInEventEmitter')
|
var mixInEventEmitter = require('mixInEventEmitter')
|
||||||
var DeviceEventEmitter = require('RCTDeviceEventEmitter')
|
var DeviceEventEmitter = require('RCTDeviceEventEmitter')
|
||||||
var NativeModules = require('NativeModules')
|
var Sockets = require('NativeModules').UdpSockets
|
||||||
var sockets = NativeModules.UdpSockets
|
|
||||||
var noop = function () {}
|
var noop = function () {}
|
||||||
var instances = 0
|
var instances = 0
|
||||||
var STATE = {
|
var STATE = {
|
||||||
|
@ -29,204 +24,191 @@ var STATE = {
|
||||||
BOUND: 2
|
BOUND: 2
|
||||||
}
|
}
|
||||||
|
|
||||||
class RCTSocket extends Component {
|
function UdpSocket(type) {
|
||||||
id: String;
|
this._id = instances++
|
||||||
_state: Integer;
|
this._state = STATE.UNBOUND
|
||||||
_address: String;
|
this._subscriptiom = DeviceEventEmitter.addListener(
|
||||||
_port: Integer;
|
'udp-' + this._id + '-data', this._onReceive.bind(this)
|
||||||
|
);
|
||||||
|
|
||||||
constructor(props) {
|
// ensure compatibility with node's EventEmitter
|
||||||
super(props)
|
if (!this.on) this.on = this.addListener.bind(this)
|
||||||
this.id = instances++
|
|
||||||
this.subscriptiom = DeviceEventEmitter.addListener(
|
|
||||||
'udp-' + this.id + '-data', this._onReceive.bind(this)
|
|
||||||
);
|
|
||||||
|
|
||||||
// ensure compatibility with node's EventEmitter
|
Sockets.createSocket(this._id, {
|
||||||
if (!this.on) this.on = this.addListener.bind(this)
|
type: type || 'udp4'
|
||||||
|
}) // later
|
||||||
|
}
|
||||||
|
|
||||||
this._state = STATE.UNBOUND
|
UdpSocket.prototype._debug = function() {
|
||||||
sockets.createSocket(this.id, {
|
// for now
|
||||||
type: props.type || 'udp4'
|
var args = [].slice.call(arguments)
|
||||||
}) // later
|
args.unshift(this._id)
|
||||||
|
console.log.apply(console, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UdpSocket.prototype.bind = function(port, address, callback) {
|
||||||
|
var self = this
|
||||||
|
|
||||||
|
if (this._state !== STATE.UNBOUND) throw new Error('Socket is already bound')
|
||||||
|
|
||||||
|
if (typeof address === 'function') {
|
||||||
|
callback = address
|
||||||
|
address = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
_debug() {
|
if (!address) address = '0.0.0.0'
|
||||||
var args = [].slice.call(arguments)
|
|
||||||
args.unshift(this.id)
|
|
||||||
console.log.apply(console, args)
|
|
||||||
}
|
|
||||||
|
|
||||||
bind(port, address, callback) {
|
if (!port) port = 0
|
||||||
var self = this
|
|
||||||
|
|
||||||
if (this._state !== STATE.UNBOUND) throw new Error('Socket is already bound')
|
if (callback) this.once('listening', callback.bind(this))
|
||||||
|
|
||||||
if (typeof address === 'function') {
|
this._state = STATE.BINDING
|
||||||
callback = address
|
this._debug('binding, address:', address, 'port:', port)
|
||||||
address = undefined
|
Sockets.bind(this._id, port, address, function(err, addr) {
|
||||||
|
if (err) {
|
||||||
|
// questionable: may want to self-destruct and
|
||||||
|
// force user to create a new socket
|
||||||
|
self._state = STATE.UNBOUND
|
||||||
|
self._debug('failed to bind', err)
|
||||||
|
return self.emit('error', err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!address) address = '0.0.0.0'
|
self._debug('bound to address:', addr.address, 'port:', addr.port)
|
||||||
|
self._address = addr.address
|
||||||
|
self._port = addr.port
|
||||||
|
self._state = STATE.BOUND
|
||||||
|
self.emit('listening')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (!port) port = 0
|
UdpSocket.prototype.close = function() {
|
||||||
|
if (this._destroyed) return
|
||||||
|
|
||||||
if (callback) this.once('listening', callback.bind(this))
|
this._destroyed = true
|
||||||
|
this._debug('closing')
|
||||||
|
this._subscription.remove();
|
||||||
|
|
||||||
this._state = STATE.BINDING
|
Sockets.close(this._id, this._debug.bind(this, 'closed'))
|
||||||
this._debug('binding, address:', address, 'port:', port)
|
this.emit('close')
|
||||||
sockets.bind(this.id, port, address, function(err, addr) {
|
}
|
||||||
if (err) {
|
|
||||||
// questionable: may want to self-destruct and
|
|
||||||
// force user to create a new socket
|
|
||||||
self._state = STATE.UNBOUND
|
|
||||||
self._debug('failed to bind', err)
|
|
||||||
return self.emit('error', err)
|
|
||||||
}
|
|
||||||
|
|
||||||
self._debug('bound to address:', addr.address, 'port:', addr.port)
|
UdpSocket.prototype._onReceive = function(info) {
|
||||||
self._address = addr.address
|
this._debug('received', info)
|
||||||
self._port = addr.port
|
|
||||||
self._state = STATE.BOUND
|
var buf = toByteArray(info.data)
|
||||||
self.emit('listening')
|
var rinfo = {
|
||||||
})
|
address: info.address,
|
||||||
|
port: info.port,
|
||||||
|
family: 'IPv4', // not necessarily
|
||||||
|
size: buf.length
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
if (typeof Buffer !== 'undefined') buf = new Buffer(buf)
|
||||||
this.subscription.remove();
|
|
||||||
|
this.emit('message', buf, rinfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* socket.send(buf, offset, length, port, address, [callback])
|
||||||
|
*
|
||||||
|
* For UDP sockets, the destination port and IP address must be
|
||||||
|
* specified. A string may be supplied for the address parameter, and it will
|
||||||
|
* be resolved with DNS. An optional callback may be specified to detect any
|
||||||
|
* DNS errors and when buf may be re-used. Note that DNS lookups will delay
|
||||||
|
* the time that a send takes place, at least until the next tick. The only
|
||||||
|
* way to know for sure that a send has taken place is to use the callback.
|
||||||
|
*
|
||||||
|
* If the socket has not been previously bound with a call to bind, it's
|
||||||
|
* assigned a random port number and bound to the "all interfaces" address
|
||||||
|
* (0.0.0.0 for udp4 sockets, ::0 for udp6 sockets).
|
||||||
|
*
|
||||||
|
* @param {Array|string} message to be sent
|
||||||
|
* @param {number} offset Offset in the buffer where the message starts.
|
||||||
|
* @param {number} length Number of bytes in the message.
|
||||||
|
* @param {number} port destination port
|
||||||
|
* @param {string} address destination IP
|
||||||
|
* @param {function} callback Callback when message is done being delivered.
|
||||||
|
* Optional.
|
||||||
|
*/
|
||||||
|
// UdpSocket.prototype.send = function (buf, host, port, cb) {
|
||||||
|
UdpSocket.prototype.send = function(buffer, offset, length, port, address, callback) {
|
||||||
|
var self = this
|
||||||
|
|
||||||
|
if (offset !== 0) throw new Error('Non-zero offset not supported yet')
|
||||||
|
|
||||||
|
if (this._state === STATE.UNBOUND) {
|
||||||
|
throw new Error('bind before sending, seriously dude')
|
||||||
|
}
|
||||||
|
else if (this._state === STATE.BINDING) {
|
||||||
|
// we're ok, GCDAsync(Udp)Socket handles queueing internally
|
||||||
}
|
}
|
||||||
|
|
||||||
_onReceive(info) {
|
callback = callback || noop
|
||||||
this._debug('received', info)
|
if (typeof buffer === 'string') {
|
||||||
|
buffer = toByteArray(buffer)
|
||||||
|
}
|
||||||
|
else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(buffer)) {
|
||||||
|
buffer = buffer.toJSON().data
|
||||||
|
}
|
||||||
|
|
||||||
var buf = toByteArray(info.data)
|
self._debug('sending', buffer)
|
||||||
var rinfo = {
|
Sockets.send(this._id, buffer, +port, address, function(err) {
|
||||||
address: info.address,
|
if (err) {
|
||||||
port: info.port,
|
self._debug('send failed', err)
|
||||||
family: 'IPv4', // not necessarily
|
return callback(err)
|
||||||
size: buf.length
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof Buffer !== 'undefined') buf = new Buffer(buf)
|
self._debug('sent')
|
||||||
|
callback()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
this.emit('message', buf, rinfo)
|
UdpSocket.prototype.address = function() {
|
||||||
|
if (this._state !== STATE.BOUND) {
|
||||||
|
throw new Error('socket is not bound yet')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
/**
|
address: this._address,
|
||||||
* socket.send(buf, offset, length, port, address, [callback])
|
port: this._port,
|
||||||
*
|
family: 'IPv4'
|
||||||
* For UDP sockets, the destination port and IP address must be
|
|
||||||
* specified. A string may be supplied for the address parameter, and it will
|
|
||||||
* be resolved with DNS. An optional callback may be specified to detect any
|
|
||||||
* DNS errors and when buf may be re-used. Note that DNS lookups will delay
|
|
||||||
* the time that a send takes place, at least until the next tick. The only
|
|
||||||
* way to know for sure that a send has taken place is to use the callback.
|
|
||||||
*
|
|
||||||
* If the socket has not been previously bound with a call to bind, it's
|
|
||||||
* assigned a random port number and bound to the "all interfaces" address
|
|
||||||
* (0.0.0.0 for udp4 sockets, ::0 for udp6 sockets).
|
|
||||||
*
|
|
||||||
* @param {Array|string} message to be sent
|
|
||||||
* @param {number} offset Offset in the buffer where the message starts.
|
|
||||||
* @param {number} length Number of bytes in the message.
|
|
||||||
* @param {number} port destination port
|
|
||||||
* @param {string} address destination IP
|
|
||||||
* @param {function} callback Callback when message is done being delivered.
|
|
||||||
* Optional.
|
|
||||||
*/
|
|
||||||
// Socket.prototype.send = function (buf, host, port, cb) {
|
|
||||||
send(buffer, offset, length, port, address, callback) {
|
|
||||||
var self = this
|
|
||||||
|
|
||||||
if (offset !== 0) throw new Error('Non-zero offset not supported yet')
|
|
||||||
|
|
||||||
if (this._state === STATE.UNBOUND) {
|
|
||||||
throw new Error('bind before sending, seriously dude')
|
|
||||||
}
|
|
||||||
else if (this._state === STATE.BINDING) {
|
|
||||||
// we're ok, GCDAsync(Udp)Socket handles queueing internally
|
|
||||||
}
|
|
||||||
|
|
||||||
callback = callback || noop
|
|
||||||
if (typeof buffer === 'string') {
|
|
||||||
buffer = toByteArray(buffer)
|
|
||||||
}
|
|
||||||
else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(buffer)) {
|
|
||||||
buffer = buffer.toJSON().data
|
|
||||||
}
|
|
||||||
|
|
||||||
self._debug('sending', buffer)
|
|
||||||
sockets.send(this.id, buffer, +port, address, function(err) {
|
|
||||||
if (err) {
|
|
||||||
self._debug('send failed', err)
|
|
||||||
return callback(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
self._debug('sent')
|
|
||||||
callback()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
address() {
|
|
||||||
if (this._state !== STATE.BOUND) {
|
|
||||||
throw new Error('socket is not bound yet')
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
address: this._address,
|
|
||||||
port: this._port,
|
|
||||||
family: 'IPv4'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
close() {
|
|
||||||
var self = this
|
|
||||||
if (this._destroyed) return
|
|
||||||
|
|
||||||
this._destroyed = true
|
|
||||||
this._debug('closing')
|
|
||||||
sockets.close(this.id, function() {
|
|
||||||
self._debug('closed')
|
|
||||||
})
|
|
||||||
|
|
||||||
this.emit('close')
|
|
||||||
}
|
|
||||||
|
|
||||||
setBroadcast(flag) {
|
|
||||||
// nothing yet
|
|
||||||
}
|
|
||||||
|
|
||||||
setTTL(ttl) {
|
|
||||||
// nothing yet
|
|
||||||
}
|
|
||||||
|
|
||||||
setMulticastTTL(ttl, callback) {
|
|
||||||
// nothing yet
|
|
||||||
}
|
|
||||||
|
|
||||||
setMulticastLoopback(flag, callback) {
|
|
||||||
// nothing yet
|
|
||||||
}
|
|
||||||
|
|
||||||
addMembership(multicastAddress, multicastInterface, callback) {
|
|
||||||
// nothing yet
|
|
||||||
}
|
|
||||||
|
|
||||||
dropMembership(multicastAddress, multicastInterface, callback) {
|
|
||||||
// nothing yet
|
|
||||||
}
|
|
||||||
|
|
||||||
ref() {
|
|
||||||
// anything?
|
|
||||||
}
|
|
||||||
|
|
||||||
unref() {
|
|
||||||
// anything?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mixInEventEmitter(RCTSocket, {
|
UdpSocket.prototype.setBroadcast = function(flag) {
|
||||||
|
// nothing yet
|
||||||
|
}
|
||||||
|
|
||||||
|
UdpSocket.prototype.setTTL = function(ttl) {
|
||||||
|
// nothing yet
|
||||||
|
}
|
||||||
|
|
||||||
|
UdpSocket.prototype.setMulticastTTL = function(ttl, callback) {
|
||||||
|
// nothing yet
|
||||||
|
}
|
||||||
|
|
||||||
|
UdpSocket.prototype.setMulticastLoopback = function(flag, callback) {
|
||||||
|
// nothing yet
|
||||||
|
}
|
||||||
|
|
||||||
|
UdpSocket.prototype.addMembership = function(multicastAddress, multicastInterface, callback) {
|
||||||
|
// nothing yet
|
||||||
|
}
|
||||||
|
|
||||||
|
UdpSocket.prototype.dropMembership = function(multicastAddress, multicastInterface, callback) {
|
||||||
|
// nothing yet
|
||||||
|
}
|
||||||
|
|
||||||
|
UdpSocket.prototype.ref = function() {
|
||||||
|
// anything?
|
||||||
|
}
|
||||||
|
|
||||||
|
UdpSocket.prototype.unref = function() {
|
||||||
|
// anything?
|
||||||
|
}
|
||||||
|
|
||||||
|
mixInEventEmitter(UdpSocket, {
|
||||||
'listening': true,
|
'listening': true,
|
||||||
'message': true,
|
'message': true,
|
||||||
'close': true,
|
'close': true,
|
||||||
|
@ -258,4 +240,4 @@ function toByteArray(obj) {
|
||||||
return new Uint8Array(uint);
|
return new Uint8Array(uint);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = RCTSocket
|
module.exports = UdpSocket
|
|
@ -4,7 +4,7 @@
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var UdpSocket = require('UdpSocket')
|
var UdpSocket = require('./UdpSocket.ios')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createSocket: function(type) {
|
createSocket: function(type) {
|
||||||
|
|
Loading…
Reference in New Issue