@babblevoice/projectrtp 2.3.7 → 2.4.0
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/.github/workflows/buildimage.yaml +65 -0
- package/lib/node.js +25 -16
- package/lib/server.js +10 -9
- package/package.json +1 -1
- package/stress/utils.js +12 -3
- package/test/interface/rtpproxyserver.js +17 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: Build
|
|
2
|
+
|
|
3
|
+
# Controls when the workflow will run
|
|
4
|
+
on:
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
push:
|
|
7
|
+
branches:
|
|
8
|
+
- 'main'
|
|
9
|
+
- 'dev'
|
|
10
|
+
tags:
|
|
11
|
+
- 'v*.*.*'
|
|
12
|
+
pull_request:
|
|
13
|
+
branches:
|
|
14
|
+
- 'main'
|
|
15
|
+
- 'dev'
|
|
16
|
+
|
|
17
|
+
#GH
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
build:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
# Get the repository's code
|
|
26
|
+
- name: Checkout
|
|
27
|
+
uses: actions/checkout@v3
|
|
28
|
+
# https://github.com/docker/setup-qemu-action
|
|
29
|
+
- name: Set up QEMU
|
|
30
|
+
uses: docker/setup-qemu-action@v1
|
|
31
|
+
# https://github.com/docker/setup-buildx-action
|
|
32
|
+
- name: Set up Docker Buildx
|
|
33
|
+
id: buildx
|
|
34
|
+
uses: docker/setup-buildx-action@v2
|
|
35
|
+
- name: Login to Docker Hub
|
|
36
|
+
if: github.event_name != 'pull_request'
|
|
37
|
+
uses: docker/login-action@v2
|
|
38
|
+
with:
|
|
39
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
40
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
41
|
+
- name: Docker meta
|
|
42
|
+
id: ourdockertags
|
|
43
|
+
uses: docker/metadata-action@v3
|
|
44
|
+
with:
|
|
45
|
+
# list of Docker images to use as base name for tags
|
|
46
|
+
images: |
|
|
47
|
+
docker.io/tinpotnick/projectrtp
|
|
48
|
+
# Docker tags based on the following events/attributes
|
|
49
|
+
tags: |
|
|
50
|
+
type=schedule
|
|
51
|
+
type=ref,event=branch
|
|
52
|
+
type=ref,event=pr
|
|
53
|
+
type=semver,pattern={{version}}
|
|
54
|
+
type=semver,pattern={{major}}.{{minor}}
|
|
55
|
+
type=semver,pattern={{major}}
|
|
56
|
+
type=sha
|
|
57
|
+
|
|
58
|
+
- name: Build and push
|
|
59
|
+
uses: docker/build-push-action@v2
|
|
60
|
+
with:
|
|
61
|
+
context: .
|
|
62
|
+
platforms: linux/amd64,linux/arm64
|
|
63
|
+
push: ${{ github.event_name != 'pull_request' }}
|
|
64
|
+
tags: ${{ steps.ourdockertags.outputs.tags }}
|
|
65
|
+
labels: ${{ steps.ourdockertags.outputs.labels }}
|
package/lib/node.js
CHANGED
|
@@ -78,7 +78,8 @@ class rtpnode {
|
|
|
78
78
|
const con = {
|
|
79
79
|
connectionid: uuidv4(),
|
|
80
80
|
connection,
|
|
81
|
-
"connectionlength": 0
|
|
81
|
+
"connectionlength": 0,
|
|
82
|
+
"mode": "connect"
|
|
82
83
|
}
|
|
83
84
|
this.connections[ con.connectionid ] = con
|
|
84
85
|
this.connection.on( "data", this._onsocketdata.bind( this, con ) )
|
|
@@ -97,7 +98,8 @@ class rtpnode {
|
|
|
97
98
|
const con = {
|
|
98
99
|
connectionid: uuidv4(),
|
|
99
100
|
connection,
|
|
100
|
-
"connectionlength": 0
|
|
101
|
+
"connectionlength": 0,
|
|
102
|
+
"mode": "listen"
|
|
101
103
|
}
|
|
102
104
|
this.connections[ con.connectionid ] = con
|
|
103
105
|
connection.setKeepAlive( true )
|
|
@@ -163,12 +165,13 @@ class rtpnode {
|
|
|
163
165
|
* @param { object } connection
|
|
164
166
|
* @returns { void }
|
|
165
167
|
*/
|
|
166
|
-
send( msg, connection ) {
|
|
168
|
+
send( msg, connection, cb = undefined ) {
|
|
167
169
|
this._post( msg, ( modifiedmsg ) => {
|
|
168
170
|
if( this._destroying ) return
|
|
169
171
|
msg.status = this.prtp.stats()
|
|
170
172
|
msg.status.instance = instance
|
|
171
173
|
connection.write( message.createmessage( modifiedmsg ) )
|
|
174
|
+
if (cb !== undefined) cb(msg)
|
|
172
175
|
} )
|
|
173
176
|
}
|
|
174
177
|
|
|
@@ -195,7 +198,9 @@ class rtpnode {
|
|
|
195
198
|
* @returns { Promise< Boolean > }
|
|
196
199
|
*/
|
|
197
200
|
async _processmessage( msg, con ) {
|
|
198
|
-
|
|
201
|
+
if( "open" == msg.channel ) return await this._openchannel( msg, con )
|
|
202
|
+
|
|
203
|
+
return this._updatechannel( msg, con )
|
|
199
204
|
}
|
|
200
205
|
|
|
201
206
|
/**
|
|
@@ -285,21 +290,25 @@ class rtpnode {
|
|
|
285
290
|
* @returns { Promise< Boolean > }
|
|
286
291
|
*/
|
|
287
292
|
async _openchannel( msg, con ) {
|
|
288
|
-
if( "open" !== msg.channel ) return false
|
|
289
293
|
con.connectionlength += 1
|
|
290
294
|
msg.forcelocal = true
|
|
291
295
|
|
|
292
|
-
const chan = await this.prtp.openchannel( msg, (
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
296
|
+
const chan = await this.prtp.openchannel( msg, ( cookie ) => {
|
|
297
|
+
// TODO: we might want to ensure the actual event has been written
|
|
298
|
+
// to the server before cleaning up the channel on our side?
|
|
299
|
+
this.send( { ...{ "id": chan.id, "uuid": chan.uuid }, ...cookie },
|
|
300
|
+
con.connection,
|
|
301
|
+
( cookie ) => {
|
|
302
|
+
if ( "close" === cookie.action ) {
|
|
303
|
+
con.connectionlength -= 1
|
|
304
|
+
channels.delete( chan.uuid )
|
|
305
|
+
|
|
306
|
+
if( 0 == con.connectionlength && "listen" == con.mode ) {
|
|
307
|
+
this.connections.delete( con.instance )
|
|
308
|
+
con.connection.destroy()
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
} )
|
|
303
312
|
} )
|
|
304
313
|
channels.set( chan.uuid, chan )
|
|
305
314
|
this.send( { ...chan, ...{ "action": "open" } }, con.connection )
|
package/lib/server.js
CHANGED
|
@@ -260,20 +260,27 @@ class channel {
|
|
|
260
260
|
/**
|
|
261
261
|
* This method forces an open channel on the same remote node.
|
|
262
262
|
* @param { object } options
|
|
263
|
+
* @param { channelcallback } cb
|
|
263
264
|
* @returns { Promise< channel > }
|
|
264
265
|
*/
|
|
265
|
-
openchannel( options =
|
|
266
|
+
openchannel( options = undefined, cb = undefined ) {
|
|
267
|
+
if( "function" == typeof options ) {
|
|
268
|
+
cb = options
|
|
269
|
+
options = {}
|
|
270
|
+
}
|
|
266
271
|
|
|
267
272
|
options.channel = "open"
|
|
268
273
|
|
|
269
274
|
const resolvepromise = new Promise( ( res ) => {
|
|
270
275
|
|
|
271
276
|
const newchannel = new channel()
|
|
277
|
+
if( cb ) newchannel.em.on( "all", cb )
|
|
278
|
+
|
|
272
279
|
newchannel.connection = this.connection
|
|
273
280
|
newchannel.channels = this.channels
|
|
274
281
|
newchannel.channels.push( newchannel )
|
|
282
|
+
newchannel.openresolve = res
|
|
275
283
|
newchannel._write( options )
|
|
276
|
-
res( newchannel )
|
|
277
284
|
} )
|
|
278
285
|
|
|
279
286
|
return resolvepromise
|
|
@@ -597,8 +604,6 @@ class channel {
|
|
|
597
604
|
* @private
|
|
598
605
|
*/
|
|
599
606
|
_runclose( msg ) {
|
|
600
|
-
if( "close" !== msg.action ) return
|
|
601
|
-
|
|
602
607
|
if( undefined !== this.openresolve ) {
|
|
603
608
|
this.openresolve()
|
|
604
609
|
delete this.openresolve
|
|
@@ -612,10 +617,6 @@ class channel {
|
|
|
612
617
|
if( 0 === this.channels.length && this.connection.sock ) this.connection.sock.destroy()
|
|
613
618
|
}
|
|
614
619
|
|
|
615
|
-
if( this.connection && this.connection.sock && !this.channels ) {
|
|
616
|
-
this.connection.sock.destroy()
|
|
617
|
-
delete this.connection.sock
|
|
618
|
-
}
|
|
619
620
|
|
|
620
621
|
channels.delete( this.id )
|
|
621
622
|
}
|
|
@@ -633,7 +634,7 @@ class channel {
|
|
|
633
634
|
this.em.emit( "all", msg )
|
|
634
635
|
this.em.emit( msg.action, msg )
|
|
635
636
|
|
|
636
|
-
this._runclose( msg )
|
|
637
|
+
if( "close" == msg.action ) this._runclose( msg )
|
|
637
638
|
}
|
|
638
639
|
|
|
639
640
|
/**
|
package/package.json
CHANGED
package/stress/utils.js
CHANGED
|
@@ -20,9 +20,18 @@ module.exports.logclosechannel = ( message, d, mstimeout ) => {
|
|
|
20
20
|
channelcount--
|
|
21
21
|
totalcount++
|
|
22
22
|
module.exports.log( message )
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
|
|
24
|
+
const score = ( d.stats.in["count"] / mstimeout * 20 ).toFixed( 2 )
|
|
25
|
+
let scoremsg = ` Score: ${ score }`
|
|
26
|
+
|
|
27
|
+
// Colour based on score: red, yellow, green
|
|
28
|
+
if( 0.25 >= score ) scoremsg = "\x1B[31m" + scoremsg
|
|
29
|
+
else if( 0.7 >= score ) scoremsg = "\x1B[33m" + scoremsg
|
|
30
|
+
else scoremsg = "\x1B[32m" + scoremsg
|
|
31
|
+
scoremsg += "\x1B[37m"
|
|
32
|
+
|
|
33
|
+
module.exports.log( `Expected number of packets: ${ Math.round( mstimeout / 20 ) }, Received: ${ d.stats.in[ "count" ] },` + scoremsg )
|
|
34
|
+
module.exports.log( `Channel closed - current count now ${ channelcount } total channels this session ${ totalcount }` )
|
|
26
35
|
}
|
|
27
36
|
|
|
28
37
|
module.exports.totalchannelcount = () => {
|
|
@@ -673,4 +673,21 @@ describe( "rtpproxy server", function() {
|
|
|
673
673
|
|
|
674
674
|
|
|
675
675
|
} )
|
|
676
|
+
it( "Ensure connection stays open with 0 channel in listen mode", async () => {
|
|
677
|
+
|
|
678
|
+
const ourport = getnextport()
|
|
679
|
+
prtp.server.clearnodes()
|
|
680
|
+
const p = await prtp.proxy.listen( undefined, "127.0.0.1", ourport )
|
|
681
|
+
const ournode = await prtp.node.connect( ourport, "127.0.0.1" )
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
const chnl = await prtp.openchannel()
|
|
685
|
+
await new Promise( ( resolve ) => { setTimeout( () => resolve(), 100 ) } )
|
|
686
|
+
await chnl.close()
|
|
687
|
+
const chnl2 = await prtp.openchannel()
|
|
688
|
+
await chnl2.close()
|
|
689
|
+
await new Promise( ( resolve ) => { setTimeout( () => resolve(), 100 ) } )
|
|
690
|
+
ournode.destroy()
|
|
691
|
+
p.destroy()
|
|
692
|
+
} )
|
|
676
693
|
} )
|