JsSIP
JsSIP is a robust and lightweight JavaScript SIP library that enables real-time communication capabilities in both browser and Node.js environments. It currently maintains version 3.13.6, with a steady release cadence indicating active development and timely updates. The library facilitates SIP over WebSocket (RFC 7118, co-authored by JsSIP's creators), supporting audio/video calls via WebRTC, and instant messaging. Its key differentiators include its dual-environment compatibility, a user-friendly yet powerful API, and demonstrated interoperability with popular SIP servers like Kamailio, Asterisk, and Mobicents. JsSIP provides a flexible foundation for integrating SIP functionality directly into web applications, abstracting the complexities of WebRTC and WebSocket signaling for developers.
Common errors
-
WebSocket connection to 'wss://...' failed: WebSocket is closed before the connection is established.
cause This error frequently indicates issues with the SIP WebSocket server's SSL/TLS certificate (if using WSS), the server being unreachable, or a misconfigured WebSocket endpoint.fixInspect your browser's developer console for more specific WebSocket errors. Verify your SIP server's SSL/TLS certificate is valid and trusted. Confirm the WebSocket server is running and accessible on the specified URL and port, and that firewalls are not blocking the connection. -
NotAllowedError: Permission denied by system
cause The user's browser or operating system has blocked access to the microphone or camera, which is required for the call's `mediaConstraints`.fixGuide the user to grant media permissions. Advise them to check their browser's site settings (e.g., camera and microphone permissions) and operating system privacy settings. Consider providing a UI element to trigger the permission prompt again. -
TypeError: Cannot read properties of undefined (reading 'call')
cause `ua` (User Agent) instance might not be properly initialized or `ua.start()` has not completed successfully before attempting to make a call.fixEnsure the `UA` instance is correctly configured and `ua.start()` is called and has had time to establish its connection before `ua.call()` is invoked. Check for errors during `ua.start()` and related event handlers (`registered`, `unregistered`, `registrationFailed`). -
Error: Invalid URI 'sip:user@domain.com'
cause The provided SIP URI format for calling or configuring the User Agent is incorrect or malformed according to SIP URI specifications.fixReview the SIP URI string (`sip:bob@example.com` in the quickstart) to ensure it adheres to the correct SIP URI syntax (e.g., `sip:user@host` or `sips:user@host`). Avoid common typos or missing components.
Warnings
- breaking In JsSIP 0.3.x, HTML5 video elements are no longer directly handled by JsSIP. Developers must now use media stream handling tools to decide when and where to attach local and remote media streams, offering more control but requiring manual DOM manipulation for media elements.
- gotcha When using secure WebSocket (WSS) connections for SIP signaling, the server must present a valid, publicly trusted SSL/TLS certificate. Browsers will reject connections to servers with self-signed, expired, or untrusted certificates, leading to `WebSocket connection failed` errors in the console.
- gotcha Browsers require explicit user consent to access the microphone and camera. If a user denies these permissions, JsSIP calls configured with `mediaConstraints` will fail with a `NotAllowedError` or `Permission denied` DOMException, preventing media capture.
- gotcha JsSIP relies on a SIP server correctly configured to support SIP over WebSocket (RFC 7118). Common misconfigurations include incorrect WebSocket path, missing TLS setup for WSS, or firewall blocks, which will prevent the JsSIP `UA` from establishing a connection.
- breaking JsSIP versions prior to 3.2.17 might use deprecated `MediaStream` API methods for WebRTC. Modern browser versions have transitioned to `MediaStreamTrack` APIs. While `webrtc-adapter` can help, directly supporting `MediaStreamTrack` is essential for compatibility.
Install
-
npm install jssip -
yarn add jssip -
pnpm add jssip
Imports
- JsSIP
const JsSIP = require('jssip');import * as JsSIP from 'jssip';
- UA
import UA from 'jssip';
import { UA } from 'jssip'; - WebSocketInterface
import { WSI } from 'jssip';import { WebSocketInterface } from 'jssip';
Quickstart
import { UA, WebSocketInterface } from 'jssip';
const socket = new WebSocketInterface('wss://sip.myhost.com');
const configuration = {
sockets : [ socket ],
uri : 'sip:alice@example.com',
password : process.env.SIP_PASSWORD ?? 'superpassword' // Use environment variables for sensitive data.
};
const ua = new UA(configuration);
ua.start();
// Register callbacks to desired call events
const eventHandlers = {
'progress': (e: any) => { // Type 'any' for brevity; consider defining specific event types
console.log('Call is in progress');
},
'failed': (e: any) => {
console.error('Call failed with cause: ' + e.data.cause);
},
'ended': (e: any) => {
console.log('Call ended with cause: ' + e.data.cause);
},
'confirmed': (e: any) => {
console.log('Call confirmed');
}
};
const options = {
eventHandlers,
mediaConstraints: { 'audio': true, 'video': true }
};
const session = ua.call('sip:bob@example.com', options);
// Example: Stop UA after some time (for demonstration)
setTimeout(() => {
console.log('Stopping User Agent...');
ua.stop();
}, 30000);