@babblevoice/projectrtp 2.5.28 → 2.5.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/index.js +6 -7
- package/lib/message.js +1 -1
- package/lib/node.js +91 -23
- package/lib/server.js +31 -12
- package/package.json +1 -1
- package/src/projectrtpchannel.cpp +6 -2
package/README.md
CHANGED
|
@@ -60,7 +60,7 @@ If you wish to build outsode of a Docker image, there are npm target scripts for
|
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
62
|
docker buildx prune
|
|
63
|
-
docker buildx build --platform linux/amd64,linux/arm64 -t tinpotnick/projectrtp:2.5.
|
|
63
|
+
docker buildx build --platform linux/amd64,linux/arm64 -t tinpotnick/projectrtp:2.5.29 . --push
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
## Example scripts
|
package/index.js
CHANGED
|
@@ -31,13 +31,13 @@ function gencerts() {
|
|
|
31
31
|
const combined = keypath + "dtls-srtp.pem"
|
|
32
32
|
|
|
33
33
|
const openssl = spawnSync( "openssl", [ "genrsa", "-out", serverkey, "4096" ] )
|
|
34
|
-
if( 0 !== openssl.status ) throw "Failed to genrsa: " + openssl.status
|
|
34
|
+
if( 0 !== openssl.status ) throw new Error( "Failed to genrsa: " + openssl.status )
|
|
35
35
|
|
|
36
36
|
const request = spawnSync( "openssl", [ "req", "-new", "-key", serverkey , "-out", servercsr, "-subj", "/C=GB/CN=projectrtp" ] )
|
|
37
|
-
if( 0 !== request.status ) throw "Failed to generate csr: " + request.status
|
|
37
|
+
if( 0 !== request.status ) throw new Error( "Failed to generate csr: " + request.status )
|
|
38
38
|
|
|
39
39
|
const sign = spawnSync( "openssl", [ "x509", "-req", "-in", servercsr, "-signkey", serverkey, "-out", servercert ] )
|
|
40
|
-
if( 0 !== sign.status ) throw "Failed to sign key: " + sign.status
|
|
40
|
+
if( 0 !== sign.status ) throw new Error( "Failed to sign key: " + sign.status )
|
|
41
41
|
|
|
42
42
|
const serverkeydata = fs.readFileSync( serverkey )
|
|
43
43
|
const servercertdata = fs.readFileSync( servercert )
|
|
@@ -407,9 +407,9 @@ class projectrtp {
|
|
|
407
407
|
run( params ) {
|
|
408
408
|
|
|
409
409
|
if( "win32" == process.platform && "x64" == process.arch ) {
|
|
410
|
-
throw "Platform not currently supported"
|
|
410
|
+
throw new Error( "Platform not currently supported" )
|
|
411
411
|
} else if( "win32" == process.platform && "ia32" == process.arch ) {
|
|
412
|
-
throw "Platform not currently supported"
|
|
412
|
+
throw new Error( "Platform not currently supported" )
|
|
413
413
|
}
|
|
414
414
|
|
|
415
415
|
if( actualprojectrtp ) return
|
|
@@ -445,7 +445,6 @@ class projectrtp {
|
|
|
445
445
|
if( !params.forcelocal && server.interface.get() ) {
|
|
446
446
|
return server.interface.get().openchannel( params, cb )
|
|
447
447
|
} else {
|
|
448
|
-
/* use local */
|
|
449
448
|
const chan = actualprojectrtp.openchannel( params, ( d ) => {
|
|
450
449
|
try{
|
|
451
450
|
if( chan.em ) {
|
|
@@ -471,7 +470,7 @@ class projectrtp {
|
|
|
471
470
|
|
|
472
471
|
/* ensure we are identicle to the node version of this object */
|
|
473
472
|
chan.openchannel = this.openchannel.bind( this )
|
|
474
|
-
|
|
473
|
+
|
|
475
474
|
return chan
|
|
476
475
|
}
|
|
477
476
|
}
|
package/lib/message.js
CHANGED
package/lib/node.js
CHANGED
|
@@ -64,7 +64,7 @@ class rtpnodeconnection {
|
|
|
64
64
|
this._processmessage( modifiedmsg )
|
|
65
65
|
} )
|
|
66
66
|
} catch( e ) {
|
|
67
|
-
console.error( "Unhandled exception in
|
|
67
|
+
console.error( "Unhandled exception in projectrtp", e )
|
|
68
68
|
}
|
|
69
69
|
} )
|
|
70
70
|
}
|
|
@@ -109,16 +109,48 @@ class rtpnodeconnection {
|
|
|
109
109
|
/**
|
|
110
110
|
* Send a message back to the main server, include stats to help with load balancing.
|
|
111
111
|
* @param { object } msg
|
|
112
|
-
* @
|
|
112
|
+
* @param { function } [ cb ]
|
|
113
|
+
* @returns { Promise | undefined }
|
|
113
114
|
*/
|
|
114
115
|
send( msg, cb = undefined ) {
|
|
116
|
+
|
|
117
|
+
let retval
|
|
118
|
+
if( !cb ) retval = new Promise( ( r ) => cb = r )
|
|
115
119
|
this.parent._post( msg, ( modifiedmsg ) => {
|
|
116
|
-
if( this._destroying )
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
this.
|
|
120
|
-
|
|
120
|
+
if( this._destroying ) {
|
|
121
|
+
return
|
|
122
|
+
}
|
|
123
|
+
modifiedmsg.status = this.parent.prtp.stats()
|
|
124
|
+
modifiedmsg.status.instance = instance
|
|
125
|
+
|
|
126
|
+
delete modifiedmsg.forcelocal
|
|
127
|
+
delete modifiedmsg.em
|
|
128
|
+
delete modifiedmsg.openchannel
|
|
129
|
+
delete modifiedmsg.close
|
|
130
|
+
delete modifiedmsg.mix
|
|
131
|
+
delete modifiedmsg.unmix
|
|
132
|
+
delete modifiedmsg.echo
|
|
133
|
+
delete modifiedmsg.play
|
|
134
|
+
delete modifiedmsg.record
|
|
135
|
+
delete modifiedmsg.direction
|
|
136
|
+
delete modifiedmsg.dtmf
|
|
137
|
+
delete modifiedmsg.remote
|
|
138
|
+
|
|
139
|
+
this.connection.write( message.createmessage( modifiedmsg ), () => {
|
|
140
|
+
cb( modifiedmsg )
|
|
141
|
+
} )
|
|
121
142
|
} )
|
|
143
|
+
|
|
144
|
+
return retval
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
#cleanup() {
|
|
148
|
+
this.connectionlength -= 1
|
|
149
|
+
|
|
150
|
+
if( 0 == this.connectionlength && "listen" == this.mode ) {
|
|
151
|
+
this.parent.connections.delete( this.connectionid )
|
|
152
|
+
this.connection.destroy()
|
|
153
|
+
}
|
|
122
154
|
}
|
|
123
155
|
|
|
124
156
|
|
|
@@ -131,25 +163,61 @@ class rtpnodeconnection {
|
|
|
131
163
|
this.connectionlength += 1
|
|
132
164
|
msg.forcelocal = true
|
|
133
165
|
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
166
|
+
const timerid = setTimeout( () => {
|
|
167
|
+
console.trace( "Timeout opening channel", msg )
|
|
168
|
+
process.exit(1)
|
|
169
|
+
}, 4000 )
|
|
170
|
+
|
|
171
|
+
let chan
|
|
172
|
+
try {
|
|
173
|
+
chan = await this.parent.prtp.openchannel( msg, ( cookie ) => {
|
|
174
|
+
|
|
175
|
+
if( !chan ) {
|
|
176
|
+
console.error( "Error opening channel - message before open", msg, cookie )
|
|
177
|
+
return
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// TODO: we might want to ensure the actual event has been written
|
|
181
|
+
// to the server before cleaning up the channel on our side?
|
|
182
|
+
const tosend = { ...{ "id": chan.id, "uuid": chan.uuid }, ...cookie }
|
|
183
|
+
|
|
184
|
+
this.send( tosend,
|
|
185
|
+
() => {
|
|
186
|
+
if ( "close" === cookie.action ) {
|
|
187
|
+
if( !chan ) {
|
|
188
|
+
const closebforeopen = { error: "unknown error opening channel", cookie, msg }
|
|
189
|
+
this.send( closebforeopen, () => {
|
|
190
|
+
this.#cleanup()
|
|
191
|
+
} )
|
|
192
|
+
return
|
|
193
|
+
}
|
|
194
|
+
channels.delete( chan.uuid )
|
|
195
|
+
this.#cleanup()
|
|
146
196
|
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
} )
|
|
197
|
+
} )
|
|
198
|
+
} )
|
|
199
|
+
} catch( e ) {
|
|
200
|
+
console.error( "Error opening channel", e )
|
|
201
|
+
const opentosend = { error: "unknown error opening channel", msg }
|
|
202
|
+
await this.send( opentosend )
|
|
203
|
+
this.#cleanup()
|
|
204
|
+
return false
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if( !chan ) {
|
|
208
|
+
console.trace( "Error opening channel", msg )
|
|
209
|
+
const opentosend = { error: "unknown error opening channel", msg }
|
|
210
|
+
await this.send( opentosend )
|
|
211
|
+
this.#cleanup()
|
|
212
|
+
return false
|
|
213
|
+
}
|
|
214
|
+
|
|
150
215
|
channels.set( chan.uuid, chan )
|
|
151
|
-
this.send( { ...chan, ...{ "action": "open" } } )
|
|
152
216
|
|
|
217
|
+
clearTimeout( timerid )
|
|
218
|
+
|
|
219
|
+
const opentosend = { ...chan, ...{ "action": "open" } }
|
|
220
|
+
this.send( opentosend )
|
|
153
221
|
return true
|
|
154
222
|
}
|
|
155
223
|
|
package/lib/server.js
CHANGED
|
@@ -177,6 +177,8 @@ class channel {
|
|
|
177
177
|
*/
|
|
178
178
|
_bridge
|
|
179
179
|
|
|
180
|
+
#connected = false
|
|
181
|
+
|
|
180
182
|
/**
|
|
181
183
|
*
|
|
182
184
|
*/
|
|
@@ -262,12 +264,15 @@ class channel {
|
|
|
262
264
|
|
|
263
265
|
newchannel.connection.sock.on( "connect", () => {
|
|
264
266
|
newchannel._write( options )
|
|
267
|
+
newchannel.#connected = true
|
|
265
268
|
if ( connectresolve ) connectresolve( newchannel )
|
|
266
269
|
} )
|
|
267
270
|
|
|
268
271
|
newchannel.opentimer = setTimeout( () => {
|
|
269
272
|
if( newchannel.openreject ) {
|
|
270
|
-
|
|
273
|
+
let addmesg = ""
|
|
274
|
+
if( newchannel.#connected ) addmesg = " - post connect"
|
|
275
|
+
newchannel.openreject( new Error( "timed out waiting for open" + addmesg ) )
|
|
271
276
|
delete newchannel.openresolve
|
|
272
277
|
delete newchannel.openreject
|
|
273
278
|
delete newchannel.opentimer
|
|
@@ -298,7 +303,7 @@ class channel {
|
|
|
298
303
|
newchannel.channels.forEach( chnl => {
|
|
299
304
|
channels.delete( chnl.id )
|
|
300
305
|
if( chnl.openreject ) {
|
|
301
|
-
chnl.openreject()
|
|
306
|
+
chnl.openreject( new Error( "Connection closed whilst waiting for open" ) )
|
|
302
307
|
clearTimeout( chnl.opentimer )
|
|
303
308
|
delete chnl.openresolve
|
|
304
309
|
delete chnl.openreject
|
|
@@ -325,11 +330,8 @@ class channel {
|
|
|
325
330
|
|
|
326
331
|
const resolvepromise = new Promise( ( resolve, reject ) => {
|
|
327
332
|
|
|
328
|
-
if
|
|
329
|
-
|
|
330
|
-
const request = JSON.parse( JSON.stringify( options ) )
|
|
331
|
-
request.channel = "open"
|
|
332
|
-
channel._createforlisten( request, node, cb, resolve, reject )
|
|
333
|
+
if( !this.connection ) {
|
|
334
|
+
reject( new Error( "No connection" ) )
|
|
333
335
|
return
|
|
334
336
|
}
|
|
335
337
|
|
|
@@ -345,7 +347,7 @@ class channel {
|
|
|
345
347
|
|
|
346
348
|
newchannel.opentimer = setTimeout( () => {
|
|
347
349
|
if( newchannel.openreject ) {
|
|
348
|
-
newchannel.openreject()
|
|
350
|
+
newchannel.openreject( new Error( "timed out waiting for open" ) )
|
|
349
351
|
delete newchannel.openresolve
|
|
350
352
|
delete newchannel.openreject
|
|
351
353
|
delete newchannel.opentimer
|
|
@@ -382,7 +384,7 @@ class channel {
|
|
|
382
384
|
|
|
383
385
|
this.closetimer = setTimeout( () => {
|
|
384
386
|
if( this.closereject ) {
|
|
385
|
-
this.closereject()
|
|
387
|
+
this.closereject( new Error( "timed out waiting for close" ) )
|
|
386
388
|
delete this.closereject
|
|
387
389
|
delete this.closeresolve
|
|
388
390
|
delete this.closetimer
|
|
@@ -396,7 +398,7 @@ class channel {
|
|
|
396
398
|
} )
|
|
397
399
|
|
|
398
400
|
if( this.openreject ) {
|
|
399
|
-
this.openreject()
|
|
401
|
+
this.openreject( new Error( "Channel closed before open" ) )
|
|
400
402
|
clearTimeout( this.opentimer )
|
|
401
403
|
delete this.openresolve
|
|
402
404
|
delete this.openreject
|
|
@@ -561,7 +563,8 @@ class channel {
|
|
|
561
563
|
*/
|
|
562
564
|
_runclose( msg ) {
|
|
563
565
|
if( this.openreject ) {
|
|
564
|
-
|
|
566
|
+
console.error( "Received close before open", msg )
|
|
567
|
+
this.openreject( new Error( "Received close before open" ) )
|
|
565
568
|
clearTimeout( this.opentimer )
|
|
566
569
|
delete this.openresolve
|
|
567
570
|
delete this.openreject
|
|
@@ -591,6 +594,21 @@ class channel {
|
|
|
591
594
|
}
|
|
592
595
|
}
|
|
593
596
|
|
|
597
|
+
#haserror( msg ) {
|
|
598
|
+
if( !msg.error ) return false
|
|
599
|
+
console.error( msg )
|
|
600
|
+
|
|
601
|
+
if( this.openreject ) {
|
|
602
|
+
this.openreject( new Error( msg.error ) )
|
|
603
|
+
clearTimeout( this.opentimer )
|
|
604
|
+
delete this.openresolve
|
|
605
|
+
delete this.openreject
|
|
606
|
+
delete this.opentimer
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
return true
|
|
610
|
+
}
|
|
611
|
+
|
|
594
612
|
/**
|
|
595
613
|
* Called by our socket to pass data back up the chain.
|
|
596
614
|
* @ignore
|
|
@@ -600,6 +618,7 @@ class channel {
|
|
|
600
618
|
msg.timestamp = ( new Date ).getTime()
|
|
601
619
|
this.history.push( msg )
|
|
602
620
|
if( this._runopen( msg ) ) return
|
|
621
|
+
if( this.#haserror( msg ) ) return
|
|
603
622
|
|
|
604
623
|
this.em.emit( "all", msg )
|
|
605
624
|
this.em.emit( msg.action, msg )
|
|
@@ -722,7 +741,7 @@ class rtpserver {
|
|
|
722
741
|
|
|
723
742
|
if( 0 === nodes.size && 0 === listeningnodes.length ) {
|
|
724
743
|
console.error( "No available RTP nodes" )
|
|
725
|
-
reject( "No available RTP nodes" )
|
|
744
|
+
reject( new Error( "No available RTP nodes" ) )
|
|
726
745
|
}
|
|
727
746
|
|
|
728
747
|
const request = JSON.parse( JSON.stringify( options ) )
|
package/package.json
CHANGED
|
@@ -347,7 +347,8 @@ void projectrtpchannel::doopen( void ) {
|
|
|
347
347
|
boost::asio::ip::udp::v4(), this->port ), ec );
|
|
348
348
|
|
|
349
349
|
if( ec ) {
|
|
350
|
-
|
|
350
|
+
auto err = std::string( "failed to bind rtp socket: " ) + std::to_string( this->port ) + std::string( ": " ) + ec.message();
|
|
351
|
+
this->badsocketopen( err.c_str() );
|
|
351
352
|
return;
|
|
352
353
|
}
|
|
353
354
|
|
|
@@ -362,7 +363,8 @@ void projectrtpchannel::doopen( void ) {
|
|
|
362
363
|
boost::asio::ip::udp::v4(), this->port + 1 ), ec );
|
|
363
364
|
|
|
364
365
|
if( ec ) {
|
|
365
|
-
|
|
366
|
+
auto err = std::string( "failed to bind rtcp socket: " ) + std::to_string( this->port + 1 ) + std::string( ": " ) + ec.message();
|
|
367
|
+
this->badsocketopen( err.c_str() );
|
|
366
368
|
return;
|
|
367
369
|
}
|
|
368
370
|
|
|
@@ -2366,10 +2368,12 @@ void getchannelstats( napi_env env, napi_value &result ) {
|
|
|
2366
2368
|
void initrtpchannel( napi_env env, napi_value &result, int32_t startport, int32_t endport ) {
|
|
2367
2369
|
napi_value ccreate;
|
|
2368
2370
|
|
|
2371
|
+
AQUIRESPINLOCK( availableportslock );
|
|
2369
2372
|
while(!availableports.empty()) availableports.pop();
|
|
2370
2373
|
for( int i = (int) startport; i < (int) endport; i = i + 2 ) {
|
|
2371
2374
|
availableports.push( i );
|
|
2372
2375
|
}
|
|
2376
|
+
RELEASESPINLOCK( availableportslock );
|
|
2373
2377
|
|
|
2374
2378
|
if( napi_ok != napi_create_function( env, "exports", NAPI_AUTO_LENGTH, channelcreate, nullptr, &ccreate ) ) return;
|
|
2375
2379
|
if( napi_ok != napi_set_named_property( env, result, "openchannel", ccreate ) ) return;
|