How do I build a callback to retrieve Call-ID for a SUBSCRIBE?

155 vistas
Ir al primer mensaje no leído

avil...@fiec.espol.edu.ec

no leída,
13 ago 2014, 2:09:21 p.m.13/8/2014
para sip...@googlegroups.com
For my websocket project, I want to SUBSCRIBE to several accounts, but I do not want to create brand new subscriptions when I refresh the page containing the SIP.UA instance. Instead I want to recover the Call-ID header for each subscription, save it in the server session using AJAX, and recover it on reload prior to re-subscribe.

The trouble is that I cannot find a place to register a callback for the SUBSCRIBE where I have access to the Call-ID.

If I do this:

var subscription = this.ua.subscribe(contact, event, options);
saveCallID(subscription.dialog.id.call_id);

...then the browser complains, rightly so, that subscription.dialog is null, since it is apparently created asynchronously.

However, if I do this:

var subscription = this.ua.subscribe(contact, event, options);
subscription.on('accepted', function(response, cause) {
console.log("RECEIVED accepted for SUBSCRIBE");
console.log(response);
})
subscription.on('notify', notifyCallback);

...the callback for the accepted event is never called, even though the callback for the notify event gets called later. I expected that since SIP.Subscription mixes the behavior for SIP.ClientContext, then it should fire all of the events defined for SIP.ClientContext, including the accepted event.

So, how can I get the Call-ID value for the SUBSCRIBE as soon as possible?

James Criscuolo

no leída,
13 ago 2014, 2:36:01 p.m.13/8/2014
para sip...@googlegroups.com,avil...@fiec.espol.edu.ec
Good call on it not emitting accepted, I just pushed a fix. Hope it helps!

avil...@fiec.espol.edu.ec

no leída,
13 ago 2014, 4:28:12 p.m.13/8/2014
para sip...@googlegroups.com,avil...@fiec.espol.edu.ec
The event is now emitted. Thanks.

However, I now have a different issue. I want to renew the subscription using the Call-ID, which I am getting from the accepted callback and storing in the server. However, when I add Call-ID as an extra header in the call to SIP.UA.subscribe(), I end up with a SUBSCRIBE request with *two* Call-ID headers:

SUBSCRIBE sip:te...@pbx.villacis.com SIP/2.0
Via: SIP/2.0/WSS 1o8mtor6hl25.invalid;branch=z9hG4bK2620393
Max-Forwards: 70
To: <sip:te...@pbx.villacis.com>
From: "Alex Villacís" <sip:avil...@pbx.villacis.com>;tag=ap2q1tsgfb
Call-ID: pvjade5g9jki36768n6a
CSeq: 5661 SUBSCRIBE
Proxy-Authorization: Digest algorithm=MD5, username="avillacis", realm="pbx.villacis.com", nonce="U+vG31PrxbMURDLXzzBhQm1UL8GiEtLk", uri="sip:te...@pbx.villacis.com", response="8b98af69d1854d6942b3d7107155f134"
Call-ID: h8gp688ou49hhsosfoh7
Event: presence
Expires: 3600
Contact: <sip:kftf...@1o8mtor6hl25.invalid;transport=ws>
Allow: ACK,CANCEL,BYE,OPTIONS,INFO,NOTIFY,MESSAGE
Supported: outbound
User-Agent: SIP.js/0.6.2
Content-Length: 0

SIP/2.0 202 OK
Via: SIP/2.0/WSS 1o8mtor6hl25.invalid;branch=z9hG4bK2620393;rport=54385;received=192.168.3.2
To: <sip:te...@pbx.villacis.com>;tag=a6a1c5f60faecf035a1ae5b6e96e979a-4018
From: "Alex Villacís" <sip:avil...@pbx.villacis.com>;tag=ap2q1tsgfb
Call-ID: pvjade5g9jki36768n6a
CSeq: 5661 SUBSCRIBE
Call-ID: h8gp688ou49hhsosfoh7
Expires: 3600
Contact: <sip:192.168.2.18:5061;transport=ws>
Server: kamailio (4.1.4 (x86_64/linux))
Content-Length: 0

NOTIFY sip:kftf...@192.168.3.2:54385;transport=ws SIP/2.0
Via: SIP/2.0/WSS 192.168.2.18:5061;branch=z9hG4bKb936.840c1070000000000000000000000000.0
To: <sip:avil...@pbx.villacis.com>;tag=ap2q1tsgfb
From: <sip:te...@pbx.villacis.com>;tag=a6a1c5f60faecf035a1ae5b6e96e979a-4018
CSeq: 2 NOTIFY
Call-ID: pvjade5g9jki36768n6a
Content-Length: 0
User-Agent: kamailio (4.1.4 (x86_64/linux))
Max-Forwards: 70
Event: presence
Contact: <sip:192.168.2.18:5061;transport=ws>
Subscription-State: active;expires=3600

SIP/2.0 481 Subscription does not exist
Via: SIP/2.0/WSS 192.168.2.18:5061;branch=z9hG4bKb936.840c1070000000000000000000000000.0
To: <sip:avil...@pbx.villacis.com>;tag=ap2q1tsgfb
From: <sip:te...@pbx.villacis.com>;tag=a6a1c5f60faecf035a1ae5b6e96e979a-4018
Call-ID: pvjade5g9jki36768n6a
CSeq: 2 NOTIFY
Supported: outbound
Content-Length: 0


As seen in the trace, the subscription with duplicate Call-ID headers gets renewed with the old header, but gets notified with the new header, which is promptly rejected. I need to build a brand-new subscription that renews a previous subscription that was made on a previous page load, by using the Call-ID. I need the Call-ID header to be replaced, rather than duplicated.

James Criscuolo

no leída,
13 ago 2014, 5:06:07 p.m.13/8/2014
para sip...@googlegroups.com,avil...@fiec.espol.edu.ec
This is an interesting issue that I don't currently think we have added the functionality for (adding extra headers that actually replace headers that aren't 'extra'), however, is there any reason you need the old subscriptions? If you call UA.stop() before going to the next page, your old subscriptions will be unsubscribed, then you can just carry over the sip addresses you subscribed to to the next page instead of the call-id's, and resubscribe to them. Alternatively, with a low expire time, the old subscriptions would go away fairly quickly, or be resubscribed to before expiring if the same page is still open(if that's what your worried about).

Thanks,
James

Contact: <sip:kftfdvdg@1o8mtor6hl25.invalid;transport=ws>

avil...@fiec.espol.edu.ec

no leída,
13 ago 2014, 5:22:21 p.m.13/8/2014
para sip...@googlegroups.com,avil...@fiec.espol.edu.ec
El miércoles, 13 de agosto de 2014 16:06:07 UTC-5, James Criscuolo escribió:
> This is an interesting issue that I don't currently think we have added the functionality for (adding extra headers that actually replace headers that aren't 'extra'), however, is there any reason you need the old subscriptions? If you call UA.stop() before going to the next page, your old subscriptions will be unsubscribed, then you can just carry over the sip addresses you subscribed to to the next page instead of the call-id's, and resubscribe to them. Alternatively, with a low expire time, the old subscriptions would go away fairly quickly, or be resubscribed to before expiring if the same page is still open(if that's what your worried about).
>

Is UA.stop() synchronous? If not, it is useless for unsubscribing before loading the next page, because the old page is unloaded before all of the required packets are transmitted. I explicitly asked for this in a previous question, and this is why. I was asking for a way to delay the unload until all the required shutdown can be done.

I cannot lower the expiry time either, because SIP.js enforces the minimum expiry time of 3600 seconds.

Joseph Frazier

no leída,
13 ago 2014, 5:37:16 p.m.13/8/2014
para sip...@googlegroups.com,avil...@fiec.espol.edu.ec
> I was asking for a way to delay the unload until all the required shutdown can be done

Yeah, I don't think there is a nice way to do this. You could have a 'beforeunload' handler that asks the user to prevent the unload if there's outstanding cleanup to be done, but that could be a considerable amount of code, not to mention poor UX.

> I cannot lower the expiry time either, because SIP.js enforces the minimum expiry time of 3600 seconds.

Hmm, this doesn't appear to be a hard minimum, according to the RFC. James, we should probably allow shorter subscriptions (and maybe automatically handle resulting 423 responses).

Joseph

James Criscuolo

no leída,
14 ago 2014, 9:21:58 a.m.14/8/2014
para sip...@googlegroups.com,avil...@fiec.espol.edu.ec
UA.stop() (or the unsubscribe part of it, at least) is synchronous. When you unsubscribe, the server will respond with a NOTIFY, but there is no need for the application to acknowledge that in any way.

avil...@fiec.espol.edu.ec

no leída,
14 ago 2014, 12:30:05 p.m.14/8/2014
para sip...@googlegroups.com,avil...@fiec.espol.edu.ec
Apparently UA.stop() is NOT synchronous. As evidence, I present the following trace. This trace was obtained after installing a beforeunload handler like this: $(window).on('beforeunload', function () { ua.stop(); });


"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | user requested closure..." sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | closing registerContext" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | emitting event newTransaction" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transaction.nict | adding event stateChanged" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transaction.nict | emitting event stateChanged" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transport | sending WebSocket message:

REGISTER sip:pbx.villacis.com SIP/2.0

Via: SIP/2.0/WSS 3u2gggnosgp0.invalid;branch=z9hG4bK1212055

Max-Forwards: 70

To: <sip:avil...@pbx.villacis.com>

From: "Alex Villacís" <sip:avil...@pbx.villacis.com>;tag=7jtj4snakb

Call-ID: 9qvgdl2frckdgco4kiampf

CSeq: 83 REGISTER

Authorization: Digest algorithm=MD5, username="avillacis", realm="pbx.villacis.com", nonce="U+zjC1Ps4d+r4O/PBviZyc32z5Y6r0LF", uri="sip:pbx.villacis.com", response="ea5edbb9f4d090fadba00557dcd3ac53"

Contact: <sip:77g5...@3u2gggnosgp0.invalid;transport=ws>;reg-id=1;+sip.instance="<urn:uuid:1fb7dd94-481a-45b3-ace2-55aeb938651f>";expires=0

Supported: path,gruu,outbound

User-Agent: SIP.js/0.6.2

Content-Length: 0




" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | unsubscribing from subscription 4ik6f0e97mk4tis2rp2c4u2mjdhu24a6a1c5f60faecf035a1ae5b6e96e979a-e17f" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | emitting event newTransaction" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transaction.nict | adding event stateChanged" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transaction.nict | emitting event stateChanged" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transport | sending WebSocket message:

SUBSCRIBE sip:avil...@pbx.villacis.com SIP/2.0

Via: SIP/2.0/WSS 3u2gggnosgp0.invalid;branch=z9hG4bK9026714

Max-Forwards: 70

To: <sip:avil...@pbx.villacis.com>

From: "Alex Villacís" <sip:avil...@pbx.villacis.com>;tag=iqtae2p0rv

Call-ID: 4ik6fb8n4rd5uimh2ps3

CSeq: 1016 SUBSCRIBE

Event: presence.winfo

Expires: 0

Contact: <sip:77g5...@3u2gggnosgp0.invalid;transport=ws>

Allow: ACK,CANCEL,BYE,OPTIONS,INFO,NOTIFY,MESSAGE

Supported: outbound

User-Agent: SIP.js/0.6.2

Content-Length: 0




" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.dialog | dialog 4ik6f0e97mk4tis2rp2c4u2mjdhu24a6a1c5f60faecf035a1ae5b6e96e979a-e17f deleted" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | new listener added to event transactionDestroyed" sip-0.6.2.js:2655
La conexión a wss://pbx.villacis.com:5061/asterisk/ws fue interrumpida mientras la página se cargaba. sip-0.6.2.js:8012
GET https://pbx.villacis.com/index.php [HTTP/1.1 302 Found 61ms]
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transport | WebSocket disconnected (code: 1000| reason: Normal closure)" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | connection state set to 1" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transaction.nict | transport error occurred, deleting non-INVITE client transaction z9hG4bK1212055" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transaction.nict | emitting event stateChanged" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | emitting event transactionDestroyed" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transaction.nict | transport error occurred, deleting non-INVITE client transaction z9hG4bK9026714" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transaction.nict | emitting event stateChanged" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | emitting event transactionDestroyed" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transport | closing WebSocket wss://pbx.villacis.com:5061/asterisk/ws" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.subscription | emitting event failed" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | emitting event disconnected" sip-0.6.2.js:2655
GET https://pbx.villacis.com/index.php [HTTP/1.1 200 OK 79ms]


As I expected to happen, the corresponding packets are queued to be sent, but the websocket is closed in the middle of the update.

Joseph Frazier

no leída,
14 ago 2014, 1:17:58 p.m.14/8/2014
para sip...@googlegroups.com,avil...@fiec.espol.edu.ec
Hey Alex,

Thanks for the details on how this is working. James and I talked about it some more, and we think the browser might be closing the WebSocket (in order to leave the page) before all of the messages are sent. If you absolutely must ensure that all the messages are sent before the page unloads, the simplest way would be to use a 'beforeunload' handler that prompts the user to confirm they want to leave the page, thereby allowing more time for the messages to be sent before the WebSocket is closed.

However, this isn't great for the user, so I'd recommend simply letting the original subscriptions expire. I've submitted a pull request that allows subscriptions shorter than an hour, but if you'd rather not wait for it to be included in a SIP.js release, you could apply the patch to your SIP.js download and use it now.

Joseph

On Thursday, August 14, 2014 12:30:05 PM UTC-4, avil...@fiec.espol.edu.ec wrote:
Apparently UA.stop() is NOT synchronous. As evidence, I present the following trace. This trace was obtained after installing a beforeunload handler like this: $(window).on('beforeunload', function () { ua.stop(); });


"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | user requested closure..." sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | closing registerContext" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | emitting event newTransaction" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transaction.nict | adding event stateChanged" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transaction.nict | emitting event stateChanged" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transport | sending WebSocket message:

REGISTER sip:pbx.villacis.com SIP/2.0

Via: SIP/2.0/WSS 3u2gggnosgp0.invalid;branch=z9hG4bK1212055

Max-Forwards: 70

To: <sip:avil...@pbx.villacis.com>

From: "Alex Villacís" <sip:avil...@pbx.villacis.com>;tag=7jtj4snakb

Call-ID: 9qvgdl2frckdgco4kiampf

CSeq: 83 REGISTER

Authorization: Digest algorithm=MD5, username="avillacis", realm="pbx.villacis.com", nonce="U+zjC1Ps4d+r4O/PBviZyc32z5Y6r0LF", uri="sip:pbx.villacis.com", response="ea5edbb9f4d090fadba00557dcd3ac53"

Contact: <sip:77g5cfiv@3u2gggnosgp0.invalid;transport=ws>;reg-id=1;+sip.instance="<urn:uuid:1fb7dd94-481a-45b3-ace2-55aeb938651f>";expires=0

Supported: path,gruu,outbound

User-Agent: SIP.js/0.6.2

Content-Length: 0




" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | unsubscribing from subscription 4ik6f0e97mk4tis2rp2c4u2mjdhu24a6a1c5f60faecf035a1ae5b6e96e979a-e17f" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.ua | emitting event newTransaction" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transaction.nict | adding event stateChanged" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transaction.nict | emitting event stateChanged" sip-0.6.2.js:2655
"Thu Aug 14 2014 11:21:13 GMT-0500 (ECT) | sip.transport | sending WebSocket message:

SUBSCRIBE sip:avil...@pbx.villacis.com SIP/2.0

Via: SIP/2.0/WSS 3u2gggnosgp0.invalid;branch=z9hG4bK9026714

Max-Forwards: 70

To: <sip:avil...@pbx.villacis.com>

From: "Alex Villacís" <sip:avil...@pbx.villacis.com>;tag=iqtae2p0rv

Call-ID: 4ik6fb8n4rd5uimh2ps3

CSeq: 1016 SUBSCRIBE

Event: presence.winfo

Expires: 0

Contact: <sip:77g5cfiv@3u2gggnosgp0.invalid;transport=ws>

avil...@fiec.espol.edu.ec

no leída,
14 ago 2014, 4:23:11 p.m.14/8/2014
para sip...@googlegroups.com,avil...@fiec.espol.edu.ec
El jueves, 14 de agosto de 2014 12:17:58 UTC-5, Joseph Frazier escribió:
> Hey Alex,
>
>
> Thanks for the details on how this is working. James and I talked about it some more, and we think the browser might be closing the WebSocket (in order to leave the page) before all of the messages are sent. If you absolutely must ensure that all the messages are sent before the page unloads, the simplest way would be to use a 'beforeunload' handler that prompts the user to confirm they want to leave the page, thereby allowing more time for the messages to be sent before the WebSocket is closed.
>
>
> However, this isn't great for the user, so I'd recommend simply letting the original subscriptions expire. I've submitted a pull request that allows subscriptions shorter than an hour, but if you'd rather not wait for it to be included in a SIP.js release, you could apply the patch to your SIP.js download and use it now.


Patch applied, and timeout accepted by Kamailio.

Now, I notice there is a "subscriptions" field in SIP.UA. Apparently there is a timer to refresh a subscription before the expiry time. However, the "subscriptions" field has a new instance of the subscription, as well as the old one, so it keeps growing and growing. I am fairly sure my code is not creating additional subscriptions on the fly. I would not have noticed this with the default timeout of 3600 seconds.

James Criscuolo

no leída,
14 ago 2014, 4:52:07 p.m.14/8/2014
para sip...@googlegroups.com,avil...@fiec.espol.edu.ec
Hi Alex,
Just pushed a fix for this, give it a shot.

Joseph Frazier

no leída,
14 ago 2014, 6:07:57 p.m.14/8/2014
para sip...@googlegroups.com,avil...@fiec.espol.edu.ec
Hey, we looked into this a little more and found that SIP.js currently doesn't refresh subscriptions correctly. I created a Github issue addressing the problem.

Joseph
Responder a todos
Responder al autor
Reenviar
0 mensajes nuevos