Skip to content

Commit 5390d5f

Browse files
authored
Merge pull request #158 from digitaltsai/SIP
First draft of SIP feature
2 parents b65874c + 306e6db commit 5390d5f

File tree

16 files changed

+1434
-7
lines changed

16 files changed

+1434
-7
lines changed

.gitignore

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ composer.lock
44
opentok.phar
55
vendor/
66
phpunit.xml
7-
sample/HelloWorld/vendor/
8-
sample/HelloWorld/cache/
9-
sample/HelloWorld/composer.lock
10-
sample/Archiving/vendor/
11-
sample/Archiving/cache/
12-
sample/Archiving/composer.lock
7+
sample/*/vendor/
8+
sample/*/cache/
9+
composer.lock

sample/SipCall/README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# OpenTok Hello SIP PHP
2+
3+
This is a simple demo app that shows how you can use the OpenTok-PHP-SDK to join a SIP call.
4+
5+
## Running the App
6+
7+
First, download the dependencies using [Composer](http://getcomposer.org) in this directory.
8+
9+
```
10+
$ ../../composer.phar install
11+
```
12+
13+
Next, input your own API Key, API Secret, and SIP configuration into the `run-demo` script file:
14+
15+
```
16+
export API_KEY=0000000
17+
export API_SECRET=abcdef1234567890abcdef01234567890abcdef
18+
export SIP_URI=sip:
19+
export SIP_USERNAME=
20+
export SIP_PASSWORD=
21+
export SIP_SECURE=false
22+
```
23+
24+
Finally, start the PHP CLI development server (requires PHP >= 5.4) using the `run-demo` script
25+
26+
```
27+
$ ./run-demo
28+
```
29+
30+
Visit <http://localhost:8080> in your browser. Open it again in a second window. Smile! You've just
31+
set up a group chat. You can
32+
33+
## Walkthrough
34+
35+
This demo application uses the same frameworks and libraries as the HelloWorld sample. If you have
36+
not already gotten familiar with the code in that project, consider doing so before continuing.
37+
38+
### Main Controller (web/index.php)
39+
40+
This serves `templates/index.php` and passes in a generated session and token. It also provides an
41+
endpoing `/sip/start` which will dial into a SIP endpoint.
42+
43+
### Main Template (templates/index.php)
44+
45+
This file simply sets up the HTML page for the JavaScript application to run, imports the
46+
JavaScript library, and passes the values created by the server into the JavaScript application
47+
inside `web/js/index.js`
48+
49+
### JavaScript Application (web/js/index.js)
50+
51+
The group chat is mostly implemented in this file. It also implements a button to send a POST
52+
request to `/sip/start`, and another button to force disconnect all running SIP calls in the session.
53+
54+
For more details, read the comments in the file or go to the
55+
[JavaScript Client Library](http://tokbox.com/opentok/libraries/client/js/) for a full reference.

sample/SipCall/composer.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"name": "sipcall-php",
3+
"minimum-stability":"dev",
4+
"require": {
5+
"slim/slim": "2.*",
6+
"gregwar/cache": "1.0.*",
7+
"opentok/opentok": "dev-master"
8+
}
9+
}

sample/SipCall/run-demo

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/sh
2+
3+
if [ -z "$API_KEY" ] || [ -z "$API_SECRET" ]
4+
then
5+
# OpenTok Project Configuration (find these at https://tokbox.com/account)
6+
export API_KEY=
7+
export API_SECRET=
8+
9+
# SIP Destination Configuration (find these with your SIP server provider)
10+
export SIP_URI=sip:
11+
export SIP_USERNAME=
12+
export SIP_PASSWORD=
13+
export SIP_SECURE=false
14+
fi
15+
16+
if [ -d "cache" ]
17+
then
18+
rm -rf cache/
19+
fi
20+
21+
php -S localhost:8080 -t web web/index.php

sample/SipCall/run-demo.bat

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
:: Why? because windows can't do an OR within the conditional
2+
IF NOT DEFINED API_KEY GOTO defkeysecret
3+
IF NOT DEFINED API_SECRET GOTO defkeysecret
4+
GOTO skipdef
5+
6+
:defkeysecret
7+
8+
:: OpenTok Project Configuration (find these at https://tokbox.com/account)
9+
SET API_KEY=
10+
SET API_SECRET=
11+
12+
:: SIP Destination Configuration (find these with your SIP server provider)
13+
SET SIP_URI=
14+
SET SIP_USERNAME=
15+
SET SIP_PASSWORD=
16+
SET SIP_SECURE=false
17+
18+
:skipdef
19+
20+
RD /q /s cache
21+
22+
php.exe -S localhost:8080 -t web web/index.php

sample/SipCall/templates/index.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Wormhole Sample App</title>
5+
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Muli:300,300italic" type='text/css'>
6+
<link rel='stylesheet' href='/stylesheets/style.css' />
7+
<link rel='stylesheet' href='/stylesheets/pattern.css' />
8+
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
9+
<script src="https://static.opentok.com/v2/js/opentok.js"></script>
10+
<script>
11+
var sessionId = "<?php echo $sessionId ?>";
12+
var token = "<?php echo $token ?>";
13+
var apiKey = "<?php echo $apiKey ?>";
14+
</script>
15+
</head>
16+
<body>
17+
<div class="main-header">
18+
<header>
19+
<h1>SIP Interconnect</h1>
20+
<h3>Test OpenTok's SIP Interconnect API</h3>
21+
</header>
22+
23+
<div id="selfPublisherContainer">
24+
<h3>Your Publisher</h3>
25+
</div>
26+
27+
<section class="panel panel-default" id="sip-controls">
28+
<a href="#" class="btn tb btn-positive" id="startSip">Start SIP Call</a>
29+
<a href="#" class="btn tb btn-negative" id="stopSip">End SIP Calls</a>
30+
</section>
31+
</div>
32+
33+
<div class="streams">
34+
<h3>WebRTC Streams</h3>
35+
<div class="main-container" id="webrtcPublisherContainer">
36+
</div>
37+
<h3>SIP Streams</h3>
38+
<div class="main-container" id="sipPublisherContainer"></div>
39+
</div>
40+
41+
42+
</body>
43+
<script src="js/index.js"></script>
44+
</html>

sample/SipCall/web/index.php

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
$autoloader = __DIR__.'/../vendor/autoload.php';
4+
if (!file_exists($autoloader)) {
5+
die('You must run `composer install` in the sample app directory');
6+
}
7+
8+
require($autoloader);
9+
10+
// remove this before push
11+
$autoloader2 = __DIR__.'/../../../vendor/autoload.php';
12+
require($autoloader2);
13+
14+
use Slim\Slim;
15+
use Gregwar\Cache\Cache;
16+
17+
use OpenTok\OpenTok;
18+
use OpenTok\MediaMode;
19+
20+
// PHP CLI webserver compatibility, serving static files
21+
$filename = __DIR__.preg_replace('#(\?.*)$#', '', $_SERVER['REQUEST_URI']);
22+
if (php_sapi_name() === 'cli-server' && is_file($filename)) {
23+
return false;
24+
}
25+
26+
// Verify that the API Key and API Secret are defined
27+
if (!(getenv('API_KEY') && getenv('API_SECRET') && getenv('SIP_URI') && getenv('SIP_SECURE'))) {
28+
die('You must define API_KEY, API_SECRET, SIP_URI, and SIP_SECURE in the run-demo file');
29+
}
30+
31+
// Initialize Slim application
32+
$app = new Slim(array(
33+
'templates.path' => __DIR__.'/../templates'
34+
));
35+
36+
// Intialize a cache, store it in the app container
37+
$app->container->singleton('cache', function() {
38+
return new Cache;
39+
});
40+
41+
// Initialize OpenTok instance, store it in the app contianer
42+
$app->container->singleton('opentok', function () {
43+
return new OpenTok(getenv('API_KEY'), getenv('API_SECRET'));
44+
});
45+
// Store the API Key in the app container
46+
$app->apiKey = getenv('API_KEY');
47+
48+
$app->sip = array(
49+
'uri' => getenv('SIP_URI'),
50+
'username' => getenv('SIP_USERNAME'),
51+
'password' => getenv('SIP_PASSWORD'),
52+
'secure' => (getenv('SIP_SECURE') === 'true')
53+
);
54+
55+
// Configure routes
56+
$app->get('/', function () use ($app) {
57+
// If a sessionId has already been created, retrieve it from the cache
58+
$sessionId = $app->cache->getOrCreate('sessionId', array(), function() use ($app) {
59+
// If the sessionId hasn't been created, create it now and store it
60+
$session = $app->opentok->createSession(array('mediaMode' => MediaMode::ROUTED));
61+
return $session->getSessionId();
62+
});
63+
64+
// Generate a fresh token for this client
65+
$token = $app->opentok->generateToken($sessionId, array('role' => 'moderator'));
66+
67+
$app->render('index.php', array(
68+
'apiKey' => $app->apiKey,
69+
'sessionId' => $sessionId,
70+
'token' => $token
71+
));
72+
});
73+
74+
$app->post('/sip/start', function () use ($app) {
75+
$sessionId = $app->request->post('sessionId');
76+
77+
// generate a token
78+
$token = $app->opentok->generateToken($sessionId, array('data' => 'sip=true'));
79+
80+
// create the options parameter
81+
$options = array(
82+
'secure' => $app->sip['secure']
83+
);
84+
if ($app->sip['username'] !== false) {
85+
$options['auth'] = array('username' => $app->sip['username'], 'password' => $app->sip['password']);
86+
}
87+
88+
// make the sip call
89+
$sipCall = $app->opentok->dial($sessionId, $token, $app->sip['uri'], $options);
90+
91+
echo $sipCall->toJson();
92+
});
93+
94+
$app->run();

sample/SipCall/web/js/index.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
var session = OT.initSession(sessionId);
2+
session.on("streamCreated", function (event) {
3+
var tokenData = event.stream.connection.data;
4+
if (tokenData && tokenData.includes("sip=true")) {
5+
var element = "sipPublisherContainer";
6+
} else {
7+
var element = "webrtcPublisherContainer";
8+
}
9+
session.subscribe(event.stream, element, { insertMode: "append" });
10+
})
11+
.connect(apiKey, token, function (err) {
12+
if (err) return;
13+
session.publish("selfPublisherContainer", {
14+
insertMode: "append",
15+
height: "120px",
16+
width: "160px"
17+
});
18+
});
19+
$('#startSip').click(function (event) {
20+
$.post('/sip/start', {sessionId: sessionId, apiKey: apiKey})
21+
.fail(function () {
22+
console.log('Failed to start SIP call - sample app server returned error.');
23+
});
24+
});
25+
$('#stopSip').click(function (event) {
26+
OT.subscribers.where().forEach(function (subscriber) {
27+
var connection = subscriber.stream.connection;
28+
if (connection.data && connection.data.includes("sip=true")) {
29+
session.forceDisconnect(connection.connectionId);
30+
}
31+
});
32+
});

0 commit comments

Comments
 (0)