beta
Kandy

WebRTC – Kandy

Kandy

Enable point-to-point voice and video calling through simple webRTC APIs

Offer high quality and low-latency communication to your customers and colleagues

  • Communication

API Button

Getting Started

In this quickstart, we will help you dip your toes into Kandy before you dive in. This guide will help you get started with the Kandy Javascript SDK.

Introduction

WebRTC is an industry standard technology that provides secure, reliable and high-definition realtime voice and video to application developers. WebRTC is designed to tolerate uncontrolled networks so you can focus on your application rather than worrying about how to get voice and video across the internet. WebRTC is also made freely available as a reference implementation and is included in popular modern web browsers.

WebRTC

Kandy is a platform that help developers who are building WebRTC applications. It provides a simple model for connecting two parties together into a call and simplifies the developer experience with its SDKs. Whilst many WebRTC scenarios may involve two applications communicating directly with each other, there are some situations where this connectivity simply is not possible due to things like Network Address Translation (NAT) and Firewall policies so Kandy provides WebRTC-standard network resources to help with this too. When you find that you need to have your application cross over between WebRTC and an existing phone system Kandy can also help you with that.

Definitions

RTC: stands for Real Time Communication

Conceptual model

Conceptual model

General picture

WebRTC

Sequence Diagram

Provisioning

This API provides a simple facade on Kandy Business Services (KBS) provisioning interface for the developers using Kandy services in their application.

In order to use this API, the developer should understand what is product, order and subscriber.

Here WebRTC is offered a product and a developer can order product into his/her inventory. Developer can subscribe to a product by creating a subscriber. The developer creates a subscriber, his credentials are generated. The developer manages this credentials. With these credentials you can start using Kandy WebRTC solution.

Provisioning Schema

Sequence Diagram

Try out the provisioning process in Postman or SwaggerHub

 

Security

WebRTC is internet standard technology that has been developed with security in mind. Browser applications that wish to use WebRTC must be operating from secure sources and the media is secured between the two parties in the call.

Quickstart Examples

Want to play around with this example for yourself? Feel free to edit this code at

codepen

Setup

Using kandy.js

To begin, you will need to include the Kandy javascript library in your application. The Kandy.js library can be found here: Kandy.js. Then you can create an Kandy instance. You'll need to pass in a configuration object which is explained below.

// Instantiate the SDK.
const { create } = Kandy;
const kandy = create(kandyConfig);

After you’ve created your instance of Kandy, you can begin playing around with it to learn its functionality and see how it fits in your application. The Kandy API reference documentation will help to explain the details of the features available.

Configuration Object

There are different Kandy instances around the globe and some private Kandy instances so the SDK is instructed about how to communicate with the Kandy platform through the configuration object: * The signalling interface which is based on REST and uses HTTPS as a transport protocol. * A notification interface which uses secure WebSockets. * Addresses of STUN and TURN servers that are used in the WebRTC ICE procedure.

The examples below also provide examples of the configuration object.

In most cases, the default values will suffice for an application. For a full list of the possible configurations, see the Configuration Documentation .

Further Reading

The best way to learn is usually by example and the best way to learn Kandy is by going through quickstarts. At the end of each quickstart, there is a link to view working examples in Codepen. These examples are great resources with which to experiment and start your own code base.

Browser Support

The Kandy JavaScript SDK currently supports Chrome and Firefox.

User Connect

Connecting and Disconnecting

In this quickstart we will cover how to connect and disconnect to the Kandy Platform using Kandy.js. We will provide snippets of code below, which together will form a working demo application.

The first step with Kandy.js is always to initialize it. You will need to know the server information for the Kandy platform that you are using for initialization. Depending on your platform, the only required configuration is the server address, as the others have generic defaults.

// Instantiate the SDK.
const { create } = Kandy;
const kandyConfig={
    // Required: Server connection configs.
    authentication: {
        subscription: {...},
        websocket: {...}
    }
    // Other feature configs.
    ...
};
const kandy = create(kandyConfig);

Since we’re going to be making a working demo, we also need some HTML. The HTML for this demo is quite simple.

<div>
    Username <input type="text" id="user-id-textbox" />
    Password <input type="password" id="password-textbox" />
</div>
<div>
    <input type="submit" value="Login" onclick="login();" />
    <input type="submit" value="Logout" onclick="logout();" />
</div>
<div id="messages"> </div>

What we have is some text boxes for username and password, buttons for login and logout, and an element for logging messages to.

And, to help our understanding of what is happening in the application, we have a function that appends logs to the div element provided.

function log(message) {
    document.getElementById('messages').innerHTML += '<div>' + message + '</div>';
}

Step 1: Connecting

When you have a username and password, then you can try to connect. An event handler can be provided for the login button as follows.

    function login() {
      kandy.connect({
        username: document.getElementById("user-id-textbox").value,
        password: document.getElementById("password-textbox").value
      });
    }

Step 2: Connection Events

The kandy.connect() function does not return a value. Instead, Kandy.js uses events to tell you when something has changed. You can find a list of the authentication events here.

To subscribe to these events, you use kandy.on(). Here is the example for our demo app:

kandy.on('auth:change', function() {
   let connection = kandy.getConnection();
   // check we are transitioning states or if we have completed connection/disconnection
   if(!connection.isPending) {
      if(connection.isConnected) {
         log("Connected as "+document.getElementById("user-id-textbox").value);
      } else {
         log("Disconnected");
      }
   } else {
      // connection state is changing... maybe let the user know
      if(connection.isConnected) {
         log("Disconnecting");
      } else {
         log("Connecting as "+document.getElementById("user-id-textbox").value);
      }
   }
});

In the above piece of code we subscribe an anonymous function to the auth:change event. Now, whenever Kandy fires off an auth:change event, that function will be called. Inside this function we call kandy.getConnection().

If something goes wrong when we try to connect (invalid credentials maybe), we want to know. Kandy.js has an auth:error event to support this.

// Listen for authentication errors.
kandy.on('auth:error', function(params) {
    log('Connect error: ' + params.error.message + ' (' + params.error.code + ')');
});

To learn more about the response from this API checkout the documentation for getConnection here.

Step 3: Disconnecting

To disconnect, you simply call disconnect.

function logout() {
    kandy.disconnect();
}

Calling this function will trigger a change in the connection state, which in turn will trigger any listeners to the auth:change event. You can therefore use you r;">auth:change listener to detect if the disconnect was successful.

Voice & Video Calls

In this quickstart, we will cover the basics of making IP calls with Kandy. Code snippets will be used to demonstrate call usage of Kandy.js, and together these snippets will form a working demo application that can be viewed at the end.

Call Configs

The user will need to connect to Kandy. We won’t cover authentication in this quickstart, so we’ll take a shortcut and steal the connect code from the User Connection Quickstart.

User interface

To interact with our demo application, we will have a basic UI that allows us to make outgoing calls and respond to incoming calls. The UI will be kept very simple, as it is not the focus of this quickstart, so it will be a straightforward set of elements for user input.

    <fieldset>
        <legend>Make a Call</legend>
        <!-- User input for making a call. -->
        <input type='button' value='Make Call' onclick='makeCall();' />
        to <input type='text' id='callee' />
        with video <input type='checkbox' id='make-with-video' />
    </fieldset>

    <fieldset>
        <legend>Respond to a Call</legend>
        <!-- User input for responding to an incoming call. -->
        <input type='button' value='Answer Call' onclick='answerCall();' />
        with video <input type='checkbox' id='answer-with-video' />
        <input type='button' value='Reject Call' onclick='rejectCall();' />
    </fieldset>

    <fieldset>
        <legend>End a Call</legend>
        <!-- User input for ending an ongoing call. -->
        <input type='button' value='End Call' onclick='endCall();' />
    </fieldset>

An important part of the UI for calls are the media containers. These containers will be used to hold the media from both sides of the call. A remote media container will always be needed for a call (both voice and video), and a local media container will be needed if you would like to display the local video of the call. The HTML elements that Kandy.js will use as media containers are empty div elements.

<fieldset>
    <legend>Video</legend>
    <!-- Media containers. -->
    Remote video: <div id="remote-container"></div>
    Local video: <div id="local-container"></div>
</fieldset>

With that, there is nothing more needed for the user interface.

Step 1: Making a Call

When the user clicks on the ‘Make Call’ button, we want our makeCall function to retrieve the information needed for the call, then make the call. Since we did not specify default media containers on initialization, we will specify them as we make the call.

/*
 *  Voice & Video Call functionality.
 */

// Variable to keep track of the call.
let callId;

// Get user input and make a call to the callee.
function makeCall() {
    // Gather call options.
    let callee = document.getElementById('callee').value;
    let withVideo = document.getElementById('make-with-video').checked;

    // Gather media containers to be used for the call.
    let remoteContainer = document.getElementById('remote-container');
    let localContainer = document.getElementById('local-container');

    log('Making call to ' + callee);
    callId = kandy.call.make(callee, {
        sendInitialVideo: withVideo,
        remoteVideoContainer: remoteContainer,
        localVideoContainer: localContainer,
        normalizeAddress: true
    });
}

Kandy’s call.make will return a unique ID that is used to keep track of the call. This ID will be used to perform operations involving the call. In this simple example, it is stored in a global variable.

Step 2: Responding to a Call

If our user receives an incoming call, they will be able to either answer or reject it with our demo application. Our demo’s answerCall and rejectCall functions will invoke Kandy’s functions of the same names.

// Answer an incoming call.
function answerCall() {
    // Gather call options.
    let withVideo = document.getElementById('answer-with-video').checked;

    // Gather media containers to be used for the call.
    let remoteContainer = document.getElementById('remote-container');
    let localContainer = document.getElementById('local-container');

    // Retrieve call state.
    let call = kandy.call.getById(callId);
    log('Answering call from ' + call.from);

    kandy.call.answer(callId, {
        sendInitialVideo: withVideo,
        remoteVideoContainer: remoteContainer,
        localVideoContainer: localContainer
    });
}

// Reject an incoming call.
function rejectCall() {
    // Retrieve call state.
    let call = kandy.call.getById(callId);
    log('Rejecting call from ' + call.from);

    kandy.call.reject(callId);
}

Note that callId has not been defined above when receiving a call. The user will receive the callId from an event, which will be covered in Step 4.

Step 3: Ending a Call

If our user has an ongoing call, they can end it by providing the call’s ID to Kandy’s call.end function, which is what our demo application will do.

// End an ongoing call.
function endCall() {
    // Retrieve call state.
    let call = kandy.call.getById(callId);
    log('Ending call with ' + call.from);

    kandy.call.end(callId);
}

Step 4: Call Events

As we use Kandy’s call functions, Kandy will emit events that provide feedback about the changes in call state. We will set listeners for these events to keep our demo application informed about Kandy state.

call:start

The call:start event informs us that an outgoing call that we made has successfully been initialized, and the callee should receive a notification about the incoming call.

// Set listener for successful call starts.
kandy.on('call:start', function(params) {
    log('Call successfully started. Waiting for response.');
});

call:error and media:error

The call:error event informs us that a problem was encountered with the call. The media:error event is more specialized in that it indicates that the call could not be made because webRTC media could not be initialized. Both events provide information about the error that occured.

// Set listener for generic call errors.
kandy.on('call:error', function(params) {
    log('Encountered error on call: ' + params.error.message);
});

// Set listener for call media errors.
kandy.on('media:error', function(params) {
    log('Call encountered media error: ' + params.error.message);
});

call:stateChange

As the call is acted upon (such as answered or rejected), its state will change. We can react to changes in the call by listening for the call:stateChange event. For our demo application, we will only act if the call was ended.

// Set listener for changes in a call's state.
kandy.on('call:stateChange', function(params) {
    log('Call state changed to: ' + params.state);

    // If the call ended, stop tracking the callId.
    if(params.state === kandy.call.states.ENDED) {
        callId = null;
    }
});

call:receive

The call:receive event informs us that we have received an incoming call. The event provides the ID of the call, then we can get more information about it from Kandy state.

// Set listener for incoming calls.
kandy.on('call:receive', function(params) {
    // Keep track of the callId.
    callId = params.callId;

    // Retrieve call information.
    call = kandy.call.getById(params.callId);
    log('Received incoming call from ' + call.from);
});

We can now call the demo application done. We’ve covered the basics of what is needed to allow a user to use call functionality.