JsSIP icon indicating copy to clipboard operation
JsSIP copied to clipboard

Subscribe support

Open ikq opened this issue 4 years ago • 68 comments

I added Subscriber.js Notifier.js to JsSIP

I tried write them according JsSIP style and lint errors. Please take a look and let me know what needs to be fixed.

I already see that *.d.ts files are missing.

The work still in progress: I want add to SUBSCRIBE Contact +sip.instance as you do in REGISTER

ikq avatar May 20 '21 15:05 ikq

Hi @ikq,

JsSIP code must have the same style in order to make it readable and maintainable. Comments before making a deeper review:

  • Debug line as the first method call in al public method implementations.
  • New line after return.
  • New line before and after call to super().
  • First conditional in a block starts in new line and last ends in a new line.
  • Conditional blocks always contain curly brackets.
  • Comments in the line above when possible.
  • Calls to debug have usually a new line above and a new line below.

Please take a certain file (ie: RTCSession.js) as a reference and try to stick to its style.

jmillan avatar May 21 '21 05:05 jmillan

@ikq

Thanks for the cleanup, :+1: We'll review the PR as we can.

jmillan avatar May 25 '21 06:05 jmillan

@ikq,

Cosmetic comment, we use camelCase in API method arguments (not in 100% of the cases, I know, but we will get there). Could you please make such change?

jmillan avatar May 27 '21 05:05 jmillan

I mostly fixed the issues.

[I thought about dialog: if you write in C++/java style, then you could add an abstract class dialog, and invite-dialog, subscriber and notifier dialogs would be his descendants. The abstract dialog class could be something like stripped version of Dialog.js without actual method implementations]

About dialog, seems:

dialog interface:

  • id (string)
  • state (number)
  • receiveRequest receive incoming request with the id

other functionality:

  • check incoming requests
  • keep set of parameters to create outgoing request.

It's already implemented in Subscriber/Notifier. [Not exactly as in Dialog.js, but the same functionality]

ikq avatar Jun 05 '21 11:06 ikq

Hi,

Super busy lately. Will come back to this when we have some time.

jmillan avatar Jun 08 '21 12:06 jmillan

H @ikq,

Dialog should be agnostic to the method. Why can't current Dialog implementation be used here? It has basically the sendRequest() method that you can call, and it will call the receiveRequest() method on your Subscriber/Notifier implementation.

jmillan avatar Jun 22 '21 14:06 jmillan

Hmm... I checked the Dialog.js code again. sendRequest and receiveRequest can be used.

I just did not consider this possibility before because I found INVITE/CANCEL/ACK specific code and properties in the Dialog (e.g. subscriber used different dialog states set).

ikq avatar Jun 22 '21 15:06 ikq

There is INVITE related code in Dialog because a dialog for INVITE method needs to behave in certain way, different to generic dialogs, but that's an implementation detail. Other clases should be able to create dialogs the same way RTCSession does.

jmillan avatar Jun 22 '21 16:06 jmillan

Hi Jose, Now subscriber and notifier used Dialog.js It passed my basic testing now.

I'll continue to test next week:

  • I cannot check subscriber authentication (my sip server don't request it).
  • subscriber with some production server.
  • subscriber with notifier.

ikq avatar Jun 24 '21 18:06 ikq

Testing of the current version has been completed successfully. (subscribe authentication was not checked)

ikq avatar Jul 07 '21 15:07 ikq

subscribe authentication checked using special test. IMHO: the subscriber/notifier is ready.

ikq avatar Jul 10 '21 13:07 ikq

I see I should change debug/debugerror to logger...

ikq avatar Aug 08 '21 10:08 ikq

Hi @ikq,

We are super busy lately. Please keep using your branch and update this PR whenever you find any issue/enhancement.

Also, tests would accelerate the adoption.

jmillan avatar Aug 18 '21 17:08 jmillan

I already use this code for my work and so far no problem.

Two browsers test can be taken from: https://github.com/ikq/subscribe_notify_test

ikq avatar Aug 20 '21 07:08 ikq

@ikq, more than an external test I mean tests in JsSIP as part of this PR, testing the clases created here.

jmillan avatar Aug 23 '21 09:08 jmillan

Hi, is there some news? I'd like to test this functionality.

N4COM avatar Sep 22 '21 09:09 N4COM

Hi, is there some news? I'd like to test this functionality.

IMHO it's stable code. [At least we use subscriber in our production, currently no issues reported]

The subscriber/notifier test can taken from https://github.com/ikq/subscribe_notify_test

ikq avatar Sep 22 '21 10:09 ikq

Hi, is there a specific reason why Subscriber and Notifier don't use the Contact header from the UA like RTCSession does? If the user provides a custom contact_uri in the UAConfiguration he would have to manually add it as a extra header to Subscriber and Notifier again, wouldn't he?

markusatm avatar Sep 22 '21 10:09 markusatm

Hi, is there some news? I'd like to test this functionality.

IMHO it's stable code. [At least we use subscriber in our production, currently no issues reported]

The subscriber/notifier test can taken from https://github.com/ikq/subscribe_notify_test

I'd like to use the official repository, so I'd like if it will be merged ASAP

N4COM avatar Sep 22 '21 10:09 N4COM

Hi, is there a specific reason why Subscriber and Notifier don't use the Contact header from the UA like RTCSession does? If the user provides a custom contact_uri in the UAConfiguration he would have to manually add it as a extra header to Subscriber and Notifier again, wouldn't he?

Yes, I'm not using the Configuration.contact_uri

In fact, I was in a hurry to do this work, and did not pay attention at all to that there is such a parameter in the configuration !

Let check, how the configuration used for INVITE:

UA.js:
   this._contact = {
      pub_gruu  : null,
      temp_gruu : null,
      uri       : this._configuration.contact_uri,

RTCSession.js:
  this._contact = this._ua.contact.toString({
      anonymous,
      outbound : true
    });

Thanks. It can be improved (use of Configuration.contact_uri)

P.S. Usage Configuration.contact_uri will modify default SUBSCRIBE contact - will be missed "+sip.instance" (that I add to default SUBSCRIBE Contact) User still can set "+sip.instance" to SUBSCRIBE Contact via custom Contact header.

ikq avatar Sep 22 '21 11:09 ikq

@ikq if you don't mind external contributions i'd be willing to take a swing at writing unit tests for this project's test framework

mitre-mgarber avatar Sep 22 '21 12:09 mitre-mgarber

if you don't mind external contributions i'd be willing to take a swing at writing unit tests for this project's test framework

Thank you, I will gladly accept your help.

I have provided an external test for 2 browsers: one is sending an SUBSCRIBE and the other is receiving it and sending a NOTIFY.

Seems in unit test should be simulated 2 instances of JsSIP one send/other receive. [I don't know how it can be written. Probably instead two JsSIP instances, can be used single that send the message itself ?] ;-)

ikq avatar Sep 22 '21 12:09 ikq

Thanks. It can be improved (use of Configuration.contact_uri)

P.S. Usage Configuration.contact_uri will modify default SUBSCRIBE contact - will be missed "+sip.instance" (that I add to default SUBSCRIBE Contact) User still can set "+sip.instance" to SUBSCRIBE Contact via custom Contact header.

@ikq Is there a specific reason to use Configuration.contact_uri? Why not just do it as in RTCSession, with this._ua.contact.toString? Then it would also use the gruu if one was provided. Or am I missing something?

stefang42 avatar Sep 22 '21 13:09 stefang42

Thank you markusatm for founding the problem. Thank you stefang42, I use your fix to build Contact in subscriber and notifier.

ikq avatar Sep 23 '21 16:09 ikq

Hi,

Yes, in order for this PR to be merged we need tests in JsSIP project.

You don't need two JsSIP instances, just one instance and you should inject a transport that you control (a FAKE transport) that you use to send JsSIP UA SUBSCRIBE|NOTIFY messages and receive and check what comes from JsSIP.

If you need some help please let us know.

jmillan avatar Sep 24 '21 10:09 jmillan

Hi, I added nodeunit test to test subscriber notifier communication.

  1. Implemented loopSocket that send message itself, but modified Call-ID in each leg. (without the modification method findDialog confuses SUBSCRIBE dialog with NOTIFY dialog)

  2. subscriber and notifier run in the same JsSIP instance and send/receive SIP messages.

The test SIP sequence is:

  • SUBSCRIBE
  • SUBSCRIBE OK
  • NOTIFY
  • NOTIFY OK
  • unSUBSCRIBE (with expires 0)
  • unSUBSCRIBE OK
  • final NOTIFY (with Subscription-State: terminated)
  • final NOTIFY OK.

The unit test work silently, but if uncomment line JsSIP.debug.enable('JsSIP:*'); can be seen complete SIP communication.

SUBSCRIBE and NOTIFY headers checking: url, method, contact, subscribe accept, notify subscription-state, content-type and body. Checked order of event sequence.

ikq avatar Sep 25 '21 20:09 ikq

@ikq if you don't mind external contributions i'd be willing to take a swing at writing unit tests for this project's test framework

@mitre-mgarber I tried to study nodeunit testing, and it seemed that something began to work out. Тhanks for the help offered, but perhaps no help is needed yet.

ikq avatar Sep 25 '21 21:09 ikq

Hi, Please check this unit test. In my opinion it is ready, well, at least for a review.

ikq avatar Sep 27 '21 18:09 ikq

Thanks a lot @ikq,

I'm quite busy at the moment but I'll take a look when I can.

jmillan avatar Sep 28 '21 13:09 jmillan

Hi @ikq,

I don't see the reason for 'dialogCreated' event in Subscriber. Is there for historical/testing purposes?

jmillan avatar Oct 05 '21 07:10 jmillan