Skip to content

Commit

Permalink
Merge pull request #158 from digitaltsai/SIP
Browse files Browse the repository at this point in the history
First draft of SIP feature
  • Loading branch information
aoberoi committed Aug 19, 2016
2 parents b65874c + 306e6db commit 5390d5f
Show file tree
Hide file tree
Showing 16 changed files with 1,434 additions and 7 deletions.
9 changes: 3 additions & 6 deletions .gitignore
Expand Up @@ -4,9 +4,6 @@ composer.lock
opentok.phar
vendor/
phpunit.xml
sample/HelloWorld/vendor/
sample/HelloWorld/cache/
sample/HelloWorld/composer.lock
sample/Archiving/vendor/
sample/Archiving/cache/
sample/Archiving/composer.lock
sample/*/vendor/
sample/*/cache/
composer.lock
55 changes: 55 additions & 0 deletions sample/SipCall/README.md
@@ -0,0 +1,55 @@
# OpenTok Hello SIP PHP

This is a simple demo app that shows how you can use the OpenTok-PHP-SDK to join a SIP call.

## Running the App

First, download the dependencies using [Composer](http://getcomposer.org) in this directory.

```
$ ../../composer.phar install
```

Next, input your own API Key, API Secret, and SIP configuration into the `run-demo` script file:

```
export API_KEY=0000000
export API_SECRET=abcdef1234567890abcdef01234567890abcdef
export SIP_URI=sip:
export SIP_USERNAME=
export SIP_PASSWORD=
export SIP_SECURE=false
```

Finally, start the PHP CLI development server (requires PHP >= 5.4) using the `run-demo` script

```
$ ./run-demo
```

Visit <http://localhost:8080> in your browser. Open it again in a second window. Smile! You've just
set up a group chat. You can

## Walkthrough

This demo application uses the same frameworks and libraries as the HelloWorld sample. If you have
not already gotten familiar with the code in that project, consider doing so before continuing.

### Main Controller (web/index.php)

This serves `templates/index.php` and passes in a generated session and token. It also provides an
endpoing `/sip/start` which will dial into a SIP endpoint.

### Main Template (templates/index.php)

This file simply sets up the HTML page for the JavaScript application to run, imports the
JavaScript library, and passes the values created by the server into the JavaScript application
inside `web/js/index.js`

### JavaScript Application (web/js/index.js)

The group chat is mostly implemented in this file. It also implements a button to send a POST
request to `/sip/start`, and another button to force disconnect all running SIP calls in the session.

For more details, read the comments in the file or go to the
[JavaScript Client Library](http://tokbox.com/opentok/libraries/client/js/) for a full reference.
9 changes: 9 additions & 0 deletions sample/SipCall/composer.json
@@ -0,0 +1,9 @@
{
"name": "sipcall-php",
"minimum-stability":"dev",
"require": {
"slim/slim": "2.*",
"gregwar/cache": "1.0.*",
"opentok/opentok": "dev-master"
}
}
21 changes: 21 additions & 0 deletions sample/SipCall/run-demo
@@ -0,0 +1,21 @@
#!/bin/sh

if [ -z "$API_KEY" ] || [ -z "$API_SECRET" ]
then
# OpenTok Project Configuration (find these at https://tokbox.com/account)
export API_KEY=
export API_SECRET=

# SIP Destination Configuration (find these with your SIP server provider)
export SIP_URI=sip:
export SIP_USERNAME=
export SIP_PASSWORD=
export SIP_SECURE=false
fi

if [ -d "cache" ]
then
rm -rf cache/
fi

php -S localhost:8080 -t web web/index.php
22 changes: 22 additions & 0 deletions sample/SipCall/run-demo.bat
@@ -0,0 +1,22 @@
:: Why? because windows can't do an OR within the conditional
IF NOT DEFINED API_KEY GOTO defkeysecret
IF NOT DEFINED API_SECRET GOTO defkeysecret
GOTO skipdef

:defkeysecret

:: OpenTok Project Configuration (find these at https://tokbox.com/account)
SET API_KEY=
SET API_SECRET=

:: SIP Destination Configuration (find these with your SIP server provider)
SET SIP_URI=
SET SIP_USERNAME=
SET SIP_PASSWORD=
SET SIP_SECURE=false

:skipdef

RD /q /s cache

php.exe -S localhost:8080 -t web web/index.php
44 changes: 44 additions & 0 deletions sample/SipCall/templates/index.php
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<title>Wormhole Sample App</title>
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Muli:300,300italic" type='text/css'>
<link rel='stylesheet' href='/stylesheets/style.css' />
<link rel='stylesheet' href='/stylesheets/pattern.css' />
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script src="https://static.opentok.com/v2/js/opentok.js"></script>
<script>
var sessionId = "<?php echo $sessionId ?>";
var token = "<?php echo $token ?>";
var apiKey = "<?php echo $apiKey ?>";
</script>
</head>
<body>
<div class="main-header">
<header>
<h1>SIP Interconnect</h1>
<h3>Test OpenTok's SIP Interconnect API</h3>
</header>

<div id="selfPublisherContainer">
<h3>Your Publisher</h3>
</div>

<section class="panel panel-default" id="sip-controls">
<a href="#" class="btn tb btn-positive" id="startSip">Start SIP Call</a>
<a href="#" class="btn tb btn-negative" id="stopSip">End SIP Calls</a>
</section>
</div>

<div class="streams">
<h3>WebRTC Streams</h3>
<div class="main-container" id="webrtcPublisherContainer">
</div>
<h3>SIP Streams</h3>
<div class="main-container" id="sipPublisherContainer"></div>
</div>


</body>
<script src="js/index.js"></script>
</html>
94 changes: 94 additions & 0 deletions sample/SipCall/web/index.php
@@ -0,0 +1,94 @@
<?php

$autoloader = __DIR__.'/../vendor/autoload.php';
if (!file_exists($autoloader)) {
die('You must run `composer install` in the sample app directory');
}

require($autoloader);

// remove this before push
$autoloader2 = __DIR__.'/../../../vendor/autoload.php';
require($autoloader2);

use Slim\Slim;
use Gregwar\Cache\Cache;

use OpenTok\OpenTok;
use OpenTok\MediaMode;

// PHP CLI webserver compatibility, serving static files
$filename = __DIR__.preg_replace('#(\?.*)$#', '', $_SERVER['REQUEST_URI']);
if (php_sapi_name() === 'cli-server' && is_file($filename)) {
return false;
}

// Verify that the API Key and API Secret are defined
if (!(getenv('API_KEY') && getenv('API_SECRET') && getenv('SIP_URI') && getenv('SIP_SECURE'))) {
die('You must define API_KEY, API_SECRET, SIP_URI, and SIP_SECURE in the run-demo file');
}

// Initialize Slim application
$app = new Slim(array(
'templates.path' => __DIR__.'/../templates'
));

// Intialize a cache, store it in the app container
$app->container->singleton('cache', function() {
return new Cache;
});

// Initialize OpenTok instance, store it in the app contianer
$app->container->singleton('opentok', function () {
return new OpenTok(getenv('API_KEY'), getenv('API_SECRET'));
});
// Store the API Key in the app container
$app->apiKey = getenv('API_KEY');

$app->sip = array(
'uri' => getenv('SIP_URI'),
'username' => getenv('SIP_USERNAME'),
'password' => getenv('SIP_PASSWORD'),
'secure' => (getenv('SIP_SECURE') === 'true')
);

// Configure routes
$app->get('/', function () use ($app) {
// If a sessionId has already been created, retrieve it from the cache
$sessionId = $app->cache->getOrCreate('sessionId', array(), function() use ($app) {
// If the sessionId hasn't been created, create it now and store it
$session = $app->opentok->createSession(array('mediaMode' => MediaMode::ROUTED));
return $session->getSessionId();
});

// Generate a fresh token for this client
$token = $app->opentok->generateToken($sessionId, array('role' => 'moderator'));

$app->render('index.php', array(
'apiKey' => $app->apiKey,
'sessionId' => $sessionId,
'token' => $token
));
});

$app->post('/sip/start', function () use ($app) {
$sessionId = $app->request->post('sessionId');

// generate a token
$token = $app->opentok->generateToken($sessionId, array('data' => 'sip=true'));

// create the options parameter
$options = array(
'secure' => $app->sip['secure']
);
if ($app->sip['username'] !== false) {
$options['auth'] = array('username' => $app->sip['username'], 'password' => $app->sip['password']);
}

// make the sip call
$sipCall = $app->opentok->dial($sessionId, $token, $app->sip['uri'], $options);

echo $sipCall->toJson();
});

$app->run();
32 changes: 32 additions & 0 deletions sample/SipCall/web/js/index.js
@@ -0,0 +1,32 @@
var session = OT.initSession(sessionId);
session.on("streamCreated", function (event) {
var tokenData = event.stream.connection.data;
if (tokenData && tokenData.includes("sip=true")) {
var element = "sipPublisherContainer";
} else {
var element = "webrtcPublisherContainer";
}
session.subscribe(event.stream, element, { insertMode: "append" });
})
.connect(apiKey, token, function (err) {
if (err) return;
session.publish("selfPublisherContainer", {
insertMode: "append",
height: "120px",
width: "160px"
});
});
$('#startSip').click(function (event) {
$.post('/sip/start', {sessionId: sessionId, apiKey: apiKey})
.fail(function () {
console.log('Failed to start SIP call - sample app server returned error.');
});
});
$('#stopSip').click(function (event) {
OT.subscribers.where().forEach(function (subscriber) {
var connection = subscriber.stream.connection;
if (connection.data && connection.data.includes("sip=true")) {
session.forceDisconnect(connection.connectionId);
}
});
});

0 comments on commit 5390d5f

Please sign in to comment.