Giter VIP home page Giter VIP logo

jscommunicator's Introduction

Introduction

JSCommunicator is a WebRTC communication tool developed in HTML, CSS and JavaScript. It supports voice, video and chat messaging using the SIP protocol over WebSockets.

Please see http://jscommunicator.org for more details about features, examples, mailing lists and the latest source code.

Server requirements

To use JSCommunicator, you require a SIP proxy that supports the SIP over WebSockets transport.

Only recent versions of the SIP proxies support WebSockets.

repro from reSIProcate http://www.resiprocate.org

Kamailio http://www.kamailio.org

See the Real-Time Communication Quick Start Guide for details about setting up a SIP and TURN server to support WebRTC calls.

Dependencies

You need to have the following JavaScript libraries available in your web server or CMS:

JsSIP The latest code on the JSCommunicator master branch works with JsSIP version 0.6.x

jQuery (v1.4 or greater has been tested)

jQuery UI

jQuery.i18n.properties

ArbiterJS (v1.0 has been tested)

Font Awesome (v4.1 or greater has been tested, earlier versions do not work)

All dependencies can be easily fetched using either of the following methods:

  • on a Debian/Ubuntu system, use the "deb-setup.sh" script

  • on other systems, see the "code_grabber" script

Getting started

For integration in static or dynamically generated web sites, frameworks and Content Management Systems, please see INTEGRATION.md

Use cases

  • Standalone:

    • include the HTML fragment into a static HTML page, possibly using Server Side Includes (SSI). Make sure the page references all the required JavaScript source files.
  • In a CMS, wiki or other publishing platform:

    • include the HTML fragment into a block in a page managed by a CMS. Configure the CMS to send the JavaScript to the user or include <script> tags within the content body with the phone fragment. The DruCall module for Drupal provides an excellent example of how to do this, see http://drucall.org

Interaction with other JavaScript applications in a web page

ArbiterJS is used to provide a loosely-coupled mechanism for integration with other JavaScript modules used in the same page/site.

For example, you can:

  • send a signal to JSCommunicator telling it which destination to dial

  • receive notifications from JSCommunicator when calls are made or received and use this information to query or update an address book or CMS, display related information about the caller in another part of the screen, etc

For an example, see the files:

event-demo.shtml event-demo.js

Credits

JSCommunicator is based on the JsSIP library and inspired by the TryIt.jssip.net and RetroRTC demo applications produced by Versatica.

License

JSCommunicator http://jscommunicator.org

Copyright (C) 2013-2015 Daniel Pocock http://danielpocock.com

The JavaScript code in this page is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License (GNU GPL) as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. The code is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.

You may distribute non-source (e.g., minimized or compacted) forms of that code without the full copy of the GNU GPL normally required provided you include this license notice and a URL through which recipients can access the Corresponding Source.

jscommunicator's People

Contributors

aavia avatar alefbt avatar chenz avatar dogsleg avatar dpocock avatar elprincipe avatar helix84 avatar injiniero avatar massar avatar mira-koffman avatar mmarto avatar tami4 avatar tdi avatar tehilazi avatar timothymctim avatar toote avatar torstehu avatar tvincent2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jscommunicator's Issues

Better UI feedback when registration failed

Currently, if registration fails due to a bad password (401 or 407 error codes) the UI shows "SIP Registration failure" but it also shows the boxes for users to try and dial or chat.

Maybe the other functionality should be disabled when registration is in this state?

Maybe the error should give a link to log in again? Currently, the user can go back to the login form by clicking the logout link (provided in the fix for #23) but it would be nice to make it more obvious that the user should try to login again.

can't correct a bad password

If the user types a bad password, the UI displays a message saying that the registration failed but it doesn't give the user a way to return to the login form.

As a workaround, the user can refresh the page.

If the login form is not enabled in the configuration, then the password/registration failure message should be displayed as usual and it should not send the user to the login form as they never would have seen the login form anyway.

Does not show local video while dialing

When dialing a video calling and waiting for the other party to answer, local video is not displayed and there is no indication that we are making a video call other than the webcam light being illuminated.

specify a timeout for connectivity checks

Currently, the connectivity checks keep running if UDP is blocked. Amongst other things, this means the callee continues to hear ringing for a long time after clicking to answer.

Usually, if UDP is not blocked, the checks will complete in less than 2 seconds. Probably need a default timeout value between 2 - 5 seconds.

support other major languages

Make versions of the HTML for other major languages (Spanish, French, German, Italian, Chinese, ...)

How does jQuery best handle internationalization?

save username and display name in local storage

JSCommunicator provides a way for users to log in with arbitrary SIP credentials (see the way it is used at https://rtc.debian.org )

Each time a user visits the site, they have to type

  • their display name (e.g. Daniel Pocock)
  • their SIP address (e.g. [email protected])
  • their password

We should avoid keeping the user password in any cache or local storage. However, maybe the display name and SIP address can be saved in local storage. It may be a good idea to provide a checkbox where the user can confirm that they want those details remembered in the browser they are using.

add messaging support

Use the jQuery tabbed panel to create a chat messaging facility within JSCommunicator

See the way messages are sent and received in http://tryit.jssip.net for API details of the send message function and the received message callback.

require_relay_candidate not working

When require_relay_candidate is true and no relay candidate is found in the SDP, an error is logged but the call appears to try and proceed anyway. It then appears to fail with a 407 error.

clear dialing box when calling?

Offer a config option to automatically clear the dialing box when making a call

It should probably not clear the box if the edit permissions on the box are disabled and the user is locked into dialing a single number or if the box is invisible

integration with local audio settings

Find out if there is some way to integrate with the local audio settings / control panel so that the user can see if their microphone is disabled and see if the gain is set to a very low value. It would be even better if the user could be given a control to change these settings or open the control panel provided by their OS.

Login form, username/display name: provide default values

It may be useful to provide default values to appear in these boxes that have a lower priority than any remembered values.

The values specified by display_name and uri are not default values as such as they always override any value that the user has remembered.

Default values, however, should not override remembered values, they should only be used when remembered values don't exist at all.

Does not perform ICE connectivity checks before ringing

JsSIP is not sending back a 183 with ICE candidates in response to an INVITE.

It just sends back 180 and ringing starts.

It only does ICE checks after answering, this is not consistent with the ICE protocol.

Consequently, people sometimes experience missing audio/video streams. This should never happen.

The issue needs to be addressed with JsSIP rather than JSCommunicator.

provide visual indication of local audio level

There is currently no visual indication if the local microphone is detecting audio.

Some other softphones display a little meter or gauge that moves up and down to indicate when the local user is speaking. This is very helpful for detecting situations where the microphone is broken, not connected to the right socket or the microphone input is disabled in the OS.

TypeMismatchError when making a call

Hello,

I tried to contact the list, but I'm getting the email returned, so trying here...

I'm testing JSCommunicator in an Ubuntu 13.10 machine, and I'm getting the account registered in a kamailio server. But when I try to make an audio call, I get an error, a JS exception, and I'm kind of stuck with it.

Firefox and Chromium show different errors, but for the same script (JSComm.js) and line (29).
Moreover, I always get this message in the web: "ERROR: failed to start call, check that microphone/webcam are connected, check browser security settings, peer may not support compatible codecs", but no popup or browser message appears requesting the access to the microphone.

Thanks in advance.

  • When using Firefox, I get this:

"make_call failed: Error: RTCPeerConnection constructor passed invalid RTCConfiguration - malformed URI: " JSComm.js:29

  • When using Chromium, I get this error:

make_call failed: TypeMismatchError: The type of an object was incompatible with the expected type of the parameter associated to the object. JSComm.js:29
DOMException {message: "The type of an object was incompatible with the ex…d type of the parameter associated to the object.", name: "TypeMismatchError", code: 17, stack: "Error: The type of an object was incompatible with…ttp://localhost/JSCommunicator/jquery.js:5:10866)", INDEX_SIZE_ERR: 1…}
code: 17
message: "The type of an object was incompatible with the expected type of the parameter associated to the object."
name: "TypeMismatchError"
stack: "Error: The type of an object was incompatible with the expected type of the parameter associated to the object.↵ at Object.RTCMediaHandler.init (http://localhost/JSCommunicator/JsSIP.js:3389:27)↵ at Object.RTCMediaHandler (http://localhost/JSCommunicator/JsSIP.js:3283:8)↵ at Object.RTCSession.connect (http://localhost/JSCommunicator/JsSIP.js:4192:26)↵ at Object.UA.call (http://localhost/JSCommunicator/JsSIP.js:5170:11)↵ at Object.window.JSCommManager.make_call (http://localhost/JSCommunicator/JSComm.js:29:250)↵ at Object.window.JSCommUI.make_call (http://localhost/JSCommunicator/JSComm.js:37:280)↵ at HTMLInputElement. (http://localhost/JSCommunicator/JSComm.js:32:479)↵ at HTMLInputElement.x.event.dispatch (http://localhost/JSCommunicator/jquery.js:5:14129)↵ at HTMLInputElement.v.handle (http://localhost/JSCommunicator/jquery.js:5:10866)

Regards,
David N.

ERROR: SIP Registration failure.

Hi,

I spent the day trying to get webrtc going, but now I am stuck.

my setup:
Basically I followed http://www.rtcquickstart.org/ with small
variations. I skipped however the DNS setup stuff.
I am using repro as sip proxy. I can make calls with jitsi and empathy.

jsscommunicator does not seem to work for me. I always get the
SIP Registration on the phone.shtml pagefailure.

I have increased the log level of repro and it complains too:

REGISTER sip:spirou.hh.de SIP/2.0
Via: SIP/2.0/WS c4nuv9hulu9f.invalid;branch=z9hG4bK9564909;received=192.168.168.97
Max-Forwards: 69
Contact: <sip:[email protected];transport=ws>;+sip.ice;reg-id=1;+sip.instance="<urn:uuid:722f588d-e0de-43a4-a72b-2c9973011dc7>";expires=3600
To: <sip:[email protected]>
From: <sip:[email protected]>;tag=qivdl4evkp
Call-ID: 1mopiqpdgdrucf1td56cq6
CSeq: 1 REGISTER
Expires: 3600
Allow: INVITE, ACK, CANCEL, BYE, UPDATE, MESSAGE, OPTIONS
Supported: path, gruu, outbound
User-Agent: JsSIP 0.5.0
Content-Length: 0


DEBUG | 20141218-165938.945 | repro | RESIP:TRANSACTION | 140341293410048 | TransactionUser.cxx:87 | Match!
DEBUG | 20141218-165938.945 | repro | RESIP | 140341293410048 | Helper.cxx:374 | Helper::makeResponse(SipReq:  REGISTER spirou.hh.de tid=9564909 cseq=1 REGISTER [email protected] / 1 from(wire) code=100 reason=
DEBUG | 20141218-165938.945 | repro | RESIP:TRANSACTION | 140341293410048 | TimerQueue.cxx:50 | Adding timer: Timer Trying tid=9564909 ms=3500
DEBUG | 20141218-165938.945 | repro | RESIP:TRANSACTION | 140341293410048 | TuSelector.cxx:70 | Send to TU: TU: DialogUsageManager size=0

REGISTER sip:spirou.hh.de SIP/2.0
Via: SIP/2.0/WS c4nuv9hulu9f.invalid;branch=z9hG4bK9564909;received=192.168.168.97
Max-Forwards: 69
Contact: <sip:[email protected];transport=ws>;+sip.ice;reg-id=1;+sip.instance="<urn:uuid:722f588d-e0de-43a4-a72b-2c9973011dc7>";expires=3600
To: <sip:[email protected]>
From: <sip:[email protected]>;tag=qivdl4evkp
Call-ID: 1mopiqpdgdrucf1td56cq6
CSeq: 1 REGISTER
Expires: 3600
Allow: INVITE, ACK, CANCEL, BYE, UPDATE, MESSAGE, OPTIONS
Supported: path, gruu, outbound
User-Agent: JsSIP 0.5.0
Content-Length: 0


INFO | 20141218-165938.945 | repro | REPRO:APP | 140341268231936 | AclStore.cxx:558 | AclStore - source address NOT trusted: 192.168.168.97:47721 WS
DEBUG | 20141218-165938.945 | repro | RESIP | 140341268231936 | Helper.cxx:374 | Helper::makeResponse(SipReq:  REGISTER spirou.hh.de tid=9564909 cseq=1 REGISTER [email protected] / 1 from(wire) code=407 reason=
INFO | 20141218-165938.945 | repro | RESIP:DUM | 140341268231936 | ServerAuthManager.cxx:460 | Sending challenge to SipReq:  REGISTER spirou.hh.de tid=9564909 cseq=1 REGISTER [email protected] / 1 from(wire)
DEBUG | 20141218-165938.945 | repro | RESIP:DUM | 140341268231936 | DialogUsageManager.cxx:983 | SEND:

SIP/2.0 407 Proxy Authentication Required
Via: SIP/2.0/WS c4nuv9hulu9f.invalid;branch=z9hG4bK9564909;received=192.168.168.97
Proxy-Authenticate: Digest nonce="1418918378:24df2c666f01f1bccd6c9d526229c961",algorithm=MD5,realm="spirou.hh.de",qop="auth,auth-int"
To: <sip:[email protected]>;tag=8310bf65
From: <sip:[email protected]>;tag=qivdl4evkp
Call-ID: 1mopiqpdgdrucf1td56cq6
CSeq: 1 REGISTER
User-Agent: repro 1.9.7
Content-Length: 0


DEBUG | 20141218-165938.945 | repro | RESIP | 140341268231936 | SipStack.cxx:594 | SEND: SipResp: 407 tid=9564909 cseq=1 REGISTER / 1 from(tu)
INFO | 20141218-165938.945 | repro | RESIP:DUM | 140341268231936 | ServerAuthManager.cxx:47 | ServerAuth challenged request SipReq:  REGISTER spirou.hh.de tid=9564909 cseq=1 REGISTER [email protected] / 1 from(wire)
DEBUG | 20141218-165938.945 | repro | RESIP:TRANSPORT | 140341293410048 | TransportSelector.cxx:1178 | Transmitting to [ V4 192.168.168.97:47721 WS target domain=unspecified mFlowKey=32 ] tlsDomain= via [ V4 192.168.168.21:5062 WS target domain=unspecified mFlowKey=0 ]

SIP/2.0 407 Proxy Authentication Required
Via: SIP/2.0/WS c4nuv9hulu9f.invalid;branch=z9hG4bK9564909;received=192.168.168.97
Proxy-Authenticate: Digest nonce="1418918378:24df2c666f01f1bccd6c9d526229c961",algorithm=MD5,realm="spirou.hh.de",qop="auth,auth-int"
To: <sip:[email protected]>;tag=8310bf65
From: <sip:[email protected]>;tag=qivdl4evkp
Call-ID: 1mopiqpdgdrucf1td56cq6
CSeq: 1 REGISTER
User-Agent: repro 1.9.7
Content-Length: 0

sigcomp id=
DEBUG | 20141218-165938.946 | repro | RESIP:TRANSPORT | 140341285017344 | TcpBaseTransport.cxx:283 | Processing write for [ V4 192.168.168.97:47721 WS target domain=unspecified mFlowKey=32 ]
DEBUG | 20141218-165938.946 | repro | RESIP:TRANSPORT | 140341285017344 | ConnectionManager.cxx:65 | Found fd 32
DEBUG | 20141218-165938.961 | repro | RESIP:TRANSPORT | 140341285017344 | Transport.cxx:382 | incoming from: [ V4 192.168.168.97:47721 WS target domain=unspecified mFlowKey=32 ]
DEBUG | 20141218-165938.961 | repro | RESIP:TRANSPORT | 140341285017344 | Connection.cxx:387 | Connection::performReads()  read=812
DEBUG | 20141218-165938.961 | repro | RESIP:TRANSACTION | 140341293410048 | TransactionUser.cxx:79 | Checking if SipReq:  REGISTER spirou.hh.de tid=5578936 cseq=2 REGISTER [email protected] / 2 from(wire) is for me
DEBUG | 20141218-165938.962 | repro | RESIP:TRANSACTION | 140341293410048 | TransactionUser.cxx:84 | Checking rule...
DEBUG | 20141218-165938.962 | repro | RESIP:TRANSACTION | 140341293410048 | MessageFilterRule.cxx:45 | Matching rule for:

REGISTER sip:spirou.hh.de SIP/2.0
Via: SIP/2.0/WS c4nuv9hulu9f.invalid;branch=z9hG4bK5578936;received=192.168.168.97
Max-Forwards: 69
Contact: <sip:[email protected];transport=ws>;+sip.ice;reg-id=1;+sip.instance="<urn:uuid:722f588d-e0de-43a4-a72b-2c9973011dc7>";expires=3600
To: <sip:[email protected]>
From: <sip:[email protected]>;tag=qivdl4evkp
Call-ID: 1mopiqpdgdrucf1td56cq6
CSeq: 2 REGISTER
Expires: 3600
Allow: INVITE, ACK, CANCEL, BYE, UPDATE, MESSAGE, OPTIONS
Proxy-Authorization: Digest algorithm=MD5, username="[email protected]", realm="spirou.hh.de", nonce="1418918378:24df2c666f01f1bccd6c9d526229c961", uri="sip:spirou.hh.de", response="106f41f6aee674371a89c9b6b6571e34", qop=auth, cnonce="hqrhaad85lcv", nc=00000001
Supported: path, gruu, outbound
User-Agent: JsSIP 0.5.0
Content-Length: 0


DEBUG | 20141218-165938.962 | repro | RESIP:TRANSACTION | 140341293410048 | TransactionUser.cxx:87 | Match!
DEBUG | 20141218-165938.962 | repro | RESIP | 140341293410048 | Helper.cxx:374 | Helper::makeResponse(SipReq:  REGISTER spirou.hh.de tid=5578936 cseq=2 REGISTER [email protected] / 2 from(wire) code=100 reason=
DEBUG | 20141218-165938.962 | repro | RESIP:TRANSACTION | 140341293410048 | TimerQueue.cxx:50 | Adding timer: Timer Trying tid=5578936 ms=3500
DEBUG | 20141218-165938.962 | repro | RESIP:TRANSACTION | 140341293410048 | TuSelector.cxx:70 | Send to TU: TU: DialogUsageManager size=0

REGISTER sip:spirou.hh.de SIP/2.0
Via: SIP/2.0/WS c4nuv9hulu9f.invalid;branch=z9hG4bK5578936;received=192.168.168.97
Max-Forwards: 69
Contact: <sip:[email protected];transport=ws>;+sip.ice;reg-id=1;+sip.instance="<urn:uuid:722f588d-e0de-43a4-a72b-2c9973011dc7>";expires=3600
To: <sip:[email protected]>
From: <sip:[email protected]>;tag=qivdl4evkp
Call-ID: 1mopiqpdgdrucf1td56cq6
CSeq: 2 REGISTER
Expires: 3600
Allow: INVITE, ACK, CANCEL, BYE, UPDATE, MESSAGE, OPTIONS
Proxy-Authorization: Digest algorithm=MD5, username="[email protected]", realm="spirou.hh.de", nonce="1418918378:24df2c666f01f1bccd6c9d526229c961", uri="sip:spirou.hh.de", response="106f41f6aee674371a89c9b6b6571e34", qop=auth, cnonce="hqrhaad85lcv", nc=00000001
Supported: path, gruu, outbound
User-Agent: JsSIP 0.5.0
Content-Length: 0


INFO | 20141218-165938.962 | repro | RESIP:DUM | 140341268231936 | ServerAuthManager.cxx:402 | Requesting credential for [email protected] @ spirou.hh.de
INFO | 20141218-165938.962 | repro | RESIP:DUM | 140341268231936 | ServerAuthManager.cxx:53 | ServerAuth requested credentials SipReq:  REGISTER spirou.hh.de tid=5578936 cseq=2 REGISTER [email protected] / 2 from(wire)
DEBUG | 20141218-165938.962 | repro | REPRO:APP | 140341335373568 | UserAuthGrabber.hxx:48 | Grabbed user info for [email protected]@spirou.hh.de :
DEBUG | 20141218-165938.962 | repro | RESIP:TRANSACTION | 140341335373568 | TuSelector.cxx:70 | Send to TU: TU: DialogUsageManager size=0

UserAuthInfo [email protected] @ spirou.hh.de A1=
INFO | 20141218-165938.962 | repro | RESIP:DUM | 140341268231936 | ServerAuthManager.cxx:131 | Checking for auth result in realm=spirou.hh.de A1=
INFO | 20141218-165938.962 | repro | RESIP:DUM | 140341268231936 | ServerAuthManager.cxx:136 | User unknown [email protected] in spirou.hh.de
DEBUG | 20141218-165938.962 | repro | RESIP | 140341268231936 | Helper.cxx:374 | Helper::makeResponse(SipReq:  REGISTER spirou.hh.de tid=5578936 cseq=2 REGISTER [email protected] / 2 from(wire) code=404 reason=User unknown.
DEBUG | 20141218-165938.962 | repro | RESIP:DUM | 140341268231936 | DialogUsageManager.cxx:983 | SEND:

SIP/2.0 404 User unknown.
Via: SIP/2.0/WS c4nuv9hulu9f.invalid;branch=z9hG4bK5578936;received=192.168.168.97
To: <sip:[email protected]>;tag=a53ad358
From: <sip:[email protected]>;tag=qivdl4evkp
Call-ID: 1mopiqpdgdrucf1td56cq6
CSeq: 2 REGISTER
User-Agent: repro 1.9.7
Content-Length: 0


DEBUG | 20141218-165938.962 | repro | RESIP | 140341268231936 | SipStack.cxx:594 | SEND: SipResp: 404 tid=5578936 cseq=2 REGISTER / 2 from(tu)
INFO | 20141218-165938.962 | repro | RESIP:DUM | 140341268231936 | ServerAuthManager.cxx:112 | ServerAuth rejected request UserAuthInfo [email protected] @ spirou.hh.de A1=
DEBUG | 20141218-165938.962 | repro | RESIP:TRANSPORT | 140341293410048 | TransportSelector.cxx:1178 | Transmitting to [ V4 192.168.168.97:47721 WS target domain=unspecified mFlowKey=32 ] tlsDomain= via [ V4 192.168.168.21:5062 WS target domain=unspecified mFlowKey=0 ]

SIP/2.0 404 User unknown.
Via: SIP/2.0/WS c4nuv9hulu9f.invalid;branch=z9hG4bK5578936;received=192.168.168.97
To: <sip:[email protected]>;tag=a53ad358
From: <sip:[email protected]>;tag=qivdl4evkp
Call-ID: 1mopiqpdgdrucf1td56cq6
CSeq: 2 REGISTER
User-Agent: repro 1.9.7
Content-Length: 0

sigcomp id=
DEBUG | 20141218-165938.962 | repro | RESIP:TRANSPORT | 140341285017344 | TcpBaseTransport.cxx:283 | Processing write for [ V4 192.168.168.97:47721 WS target domain=unspecified mFlowKey=32 ]
DEBUG | 20141218-165938.962 | repro | RESIP:TRANSPORT | 140341285017344 | ConnectionManager.cxx:65 | Found fd 32

´´´


However I have a user "web" added to the repro-webinterface. Users "win" and "lin" work in jitsi and empathy. The line UserAuthInfo [email protected] @ spirou.hh.de looks funny...

but I have no idea howto fix this. 

start sending DTMF as soon as user presses button

At present,

  • DTMF is sent after the button click is released
  • the DTMF duration is a fixed value (not the length of the button press)

As it is a fixed duration, we should send the DTMF indication as soon as the user presses the button

Chat window too small

I can barely see 3 lines of chat. Please make it a way bigger. Also, best would be if it was resizeable, or automatically matching the window size.

display an alert if other active registrations exist

SIP allows multiple simultaneous registrations

Stateful proxies can fork INVITEs to all registered UAs but this is not always desirable.

It would be useful to show the user if other registrations are still active, this may alert them to the fact that they are still logged in from another PC, another browser or another tab.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.