如何使用Asterisk ARI与socket.io& Node.js的

时间:2015-10-05 15:14:22

标签: javascript jquery node.js socket.io asterisk

最近一直在处理asterisk,Linux,node.js以及最近的socket.io,这样我最终可以为星号制作实时的web应用程序。

因此,作为一个受过教育的猜测,ave能够看到Node.js就像是Asterisk和Socket之间的中间人。但我不知道如何通过socket.io将信息从星号提取到网页。

我一直在研究socket.io,并且已经失去了几天如何将它们联系起来,所以我可以举例说,记录发生在停滞状态的事件或在电话会议中取出当前的电话,只是任何事情在这一点上,由于ARI相对较新,据我所知,这是一个很难解决的问题。

我已将下面的3个文件链接起来,让您了解一直在做什么,bridge-mixed.js基于星号ARI文档中给出的示例。

我可以通过node.js运行该文件,拨打我在extensions.conf文件中指定的扩展名,当第一个用户输入会议播放音乐时,一旦超过1个用户进入,则停止音乐。

至于其他两个文件,它只是一个基本的socket.io应用程序,已经通过YouTube指南一步一步地了解它是如何工作的。

我只需要一些简单的例子来说明如何塑造它们或让它们协同工作,开始为星号制作实时的web应用程序。

即使我能以某种方式通过socket.io& amp;将某个停滞事件发送到网页。 Node.js的。

希望你们能够提供一些见解或指导,因为我现在真的迷失了。

桥mixed.js

    /*jshint node:true*/
'use strict';

var ari = require('ari-client');
var util = require('util');
var chanArr =[];

ari.connect('http://localhost:0001', 'asterisk', 'asterisk', clientLoaded);

// handler for client being loaded
function clientLoaded (err, client) {
  if (err) {
    throw err;
  }

  // find or create a holding bridge
  var bridge = null;
  client.bridges.list(function(err, bridges) {
    if (err) {
      throw err;
    }

    bridge = bridges.filter(function(candidate) {
      return candidate.bridge_type === 'mixing';
    })[0];

    if (bridge) {
      console.log(util.format('Using bridge %s', bridge.id));
    } else {
      client.bridges.create({type: 'mixing'}, function(err, newBridge) {
        if (err) {
          throw err;
        }

        bridge = newBridge;
        console.log(util.format('Created bridge %s', bridge.id));
      });
    }
  });

  // handler for StasisStart event
  function stasisStart(event, channel) {
    console.log(util.format(
        'Channel %s just entered our application, adding it to bridge %s',
        channel.name,
        bridge.id));



    channel.answer(function(err) {
      if (err) {
        throw err;
      }

      bridge.addChannel({channel: channel.id}, function(err) {
        chanArr.push(channel)

        if (err) {
          throw err;
        } 


        //If else statement to start music for first user entering channel, music will stop once more than 1 enters the channel.
 if(chanArr.length <= 1){
        bridge.startMoh(function(err) {
          if (err) {
            throw err;
          }
        });
      }else{
        bridge.stopMoh(function(err) {
          if (err) {
            throw err;
          }
        });
      }

      });
    });
  }

  // handler for StasisEnd event
  function stasisEnd(event, channel) {        
    chanArr = null;
    console.log(util.format(
        'Channel %s just left our application', channel.name));
  }

  client.on('StasisStart', stasisStart);
  client.on('StasisEnd', stasisEnd);

  client.start('bridge-hold');
}

然后下面是一个非常基本的socket.io功能和html页面:

app.js

    var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server),
nicknames = [];

server.listen(0001);

app.get('/', function (req, res) {
    res.sendfile(__dirname + '/index.html');
});

io.sockets.on('connection', function (socket) {
    socket.on('new user', function (data, callback) {
        if (nicknames.indexOf(data) != -1) {
            callback(false);
        } else {
            callback(true);
            socket.nickname = data;
            nicknames.push(socket.nickname);
            updateNicknames();
        }
    });

    function updateNicknames() {
        io.sockets.emit('usernames', nicknames);
    }

    socket.on('send message', function (data) {
        io.sockets.emit('new message', {
            msg : data,
            nick : socket.nickname
        });
    });

    socket.on('disconnect', function (data) {
        if (!socket.nickname)
            return;
        nicknames.splice(nicknames.indexOf(socket.nickname), 1);
        updateNicknames();
    });
});

的index.html

<html>
    <head>
        <title> Chat with socket.io and node.js</title>
        <style>
            #chat{
            height:500px;
            }

            #contentWrap{
            display:none;
            }

            #chatWrap{
            float:left;
            border:1px #000 solid;
            }

            .error{
            color:red;
            }

            .whisper{
            color:gray;
            font-style:italic;
            }


        </style>
    </head>
    <body>

        <div id="nickWrap">
            <p>Enter a Username</p>
            <p id="nickError"></p>
            <form id="setNick">
                <input size="35" id="nickname"></input>
                <input type="submit"></input>
            </form>
        </div>

        <div id="contentWrap">
            <div id="chatWrap">
                <div id="chat"></div>
                <form id="send-message">
                    <input size="35" id="message"></input>
                    <input type="submit"></input>
                </form> 
            </div>
            <div id="users"></div>
        </div>

        <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
        <script src="https://cdn.socket.io/socket.io-1.3.6.js"></script>
        <script>
            jQuery(function($){
            var socket = io.connect();
            var $nickForm = $('#setNick');
            var $nickError = $('#nickError');
            var $nickBox = $('#nickname');
            var $users = $('#users');
            var $messageForm = $('#send-message');
            var $messageBox = $('#message');
            var $chat = $('#chat');

            $nickForm.submit(function(e){
            e.preventDefault();
            socket.emit('new user', $nickBox.val(), function(data){
            if(data){
            $('#nickWrap').hide();
            $('#contentWrap').show();
            } else{
            $nickError.html('That username is already taken! Try Again.');
            }
            });
            $nickBox.val('');
            });

            socket.on('usernames', function(data){
            var html ='';
            for(i=0; i < data.length; i++){
                    html += data[i] + '<br/>'
                    }
                    $users.html(html);
                    });

                    $messageForm.submit(function(e){
                    e.preventDefault();
                    socket.emit('send message', $messageBox.val(), function(data){
                    $chat.append('<span class="error"><b>' + data + "</span><br/>");
                        });
                        $messageBox.val('');
                        });

                        socket.on('new message', function(data){
                        $chat.append('<span class="msg"><b>' + data.nick + ': </b>' + data.msg + "</span><br/>");
                        });

                        socket.on('whisper', function(data){
                        $chat.append('<span class="whisper"><b>' + data.nick + ': </b>' + data.msg + "</span><br/>");
                        });

                        });
                    </script>
                </body>
            </html>

1 个答案:

答案 0 :(得分:1)

因此,经过一些跟踪和错误之后,可以通过有效地合并bridge-mixed.js&amp;和它们来协同工作。 app.js文件。完成后,我可以通过ARI客户端开始访问星号方面的信息,并开始通过socket.io将其传递给作为星号前端的实时Web应用程序。

当前发布的代码只是将当前的来电者姓名附加到网页上,但它是一个基本的例子,它应该是一个很好的踏脚石,看看你能做些什么,因为信息可以很容易地开始使用JQuery开始做所有好事....例如,Muting调用,桥接来自会议的踢用户。这些是我目前正在处理的事情,将来会更新。

我希望这有助于某人。

app.js(ARI客户端和Socket.io服务器端)

ARI函数和socket.io服务器端。

var ari = require('ari-client');
var util = require('util');
var chanArr = [];
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server);

//ARI client
ari.connect('http://localhost:8088', 'asterisk', 'asterisk', clientLoaded);

function clientLoaded(err, client) {
    if (err) {
        throw err;
    }
    // find or create a holding bridges
    var bridge = null;
    client.bridges.list(function (err, bridges) {
        if (err) {
            throw err;
        }

        bridge = bridges.filter(function (candidate) {
                return candidate.bridge_type === 'mixing';
            })[0];

        if (bridge) {
            console.log(util.format('Using bridge %s', bridge.id));
        } else {
            client.bridges.create({
                type : 'mixing'
            }, function (err, newBridge) {
                if (err) {
                    throw err;
                }

                bridge = newBridge;
                console.log(util.format('Created bridge %s', bridge.id));
            });
        }
    });

    // handler for StasisStart event
    function stasisStart(event, channel) {
        console.log(util.format(
                'Channel %s just entered our application, adding it to bridge %s',
                channel.name,
                bridge.id));

        channel.answer(function (err) {
            if (err) {
                throw err;
            }

            bridge.addChannel({
                channel : channel.id
            }, function (err) {
                var id = chanArr.push(channel.name)
                    console.log("User: " + channel.name);
                if (err) {
                    throw err;
                }

                //If else statement to start music for first user entering channel, music will stop once more than 1 enters the channel.
                if (chanArr.length <= 1) {
                    bridge.startMoh(function (err) {
                        if (err) {
                            throw err;
                        }
                    });
                } else {
                    bridge.stopMoh(function (err) {
                        if (err) {
                            throw err;
                        }
                    });
                }

            });
        });
    }

    // handler for StasisEnd event
    function stasisEnd(event, channel) {
        chanArr = null;
        console.log(util.format(
                'Channel %s just left our application', channel.name));
    }
    client.on('StasisStart', stasisStart);
    client.on('StasisEnd', stasisEnd);
    client.start('bridge-hold');
}

//Socket.io logic here
server.listen(3009, function () {
    console.log('listening on *:3009');
});

app.use(express.static(__dirname + '/public'));
app.get('/', function (req, res) {
    res.sendfile(__dirname + "/testPage.html");
});

io.sockets.on('connection', function () {
    updateSip();
});

function updateSip() {
    io.sockets.emit('sip', chanArr);
}

<强> testPage.html

Web应用程序前端。

<html>
    <head>
        <title> Chat with socket.io and node.js</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
            <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
                <link href="https://gitcdn.github.io/bootstrap-toggle/2.2.0/css/bootstrap-toggle.min.css" rel="stylesheet">
                    <link href="/css/style.css" rel="stylesheet" type="text/css">   
                    </head>
                    <body>

                        <nav class="navbar navbar-inverse navbar-fixed-top">
                            <div class="navbar-header">
                                <div class="navbar-brand">Asterisk ARI Test Application</div>
                            </div>
                            <div id="navbar" class="navbar-collapse collapse">
                            </div>
                        </nav>

                        <div class="main-bridge">
                            <div class="container">
                                <div class="jumbotron content-A">
                                    <form class="test-ari">
                                        <p class="lead">Enter the number you want to call.</p>
                                        <div class="input-group input-group-lg">
                                            <input type="tel" class="form-control" placeholder="Phone Number" aria-describedby="sizing-addon1" required="" /> 
                                            <span class="input-group-btn">
                                                <button class="btn btn-default" type="submit">Call Back Now</button>
                                            </span>
                                        </div>
                                    </form>
                                </div>
                            </div>
                        </div>

                        <div class="secondary-bridge" id="sip">
                            <h3 class="conf-head">Conference call</h3>
                            <div class="panel panel-default ">
                                <div class="panel-heading " >
                                    <h3 class="panel-title"><div id="sip"></div></h3>
                                </div>
                                <div class="panel-body">
                                    <input type="checkbox" data-on="Voice" data-off="Muted" checked data-toggle="toggle" data-onstyle="success" data-offstyle="danger">
                                        <button class="btn btn-default kick" id="kick" data-toggle="modal" data-target="#myModal" type="submit">Kick</button>
                                    </div>
                                </div>
                            </div>

                            <!-- Modal -->
                            <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                                <div class="modal-dialog" role="document">
                                    <div class="modal-content">
                                        <div class="modal-header">
                                            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                                            <h4 class="modal-title" id="myModalLabel">Kick user</h4>
                                        </div>
                                        <div class="modal-body">
                                            Are you you want to kick this user?
                                        </div>
                                        <div class="modal-footer">
                                            <button type="button" class="btn btn-default" data-dismiss="modal">No</button>
                                            <button type="button" class="btn btn-primary">Yes</button>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <footer class="footer">
                                <p>&copy; User 2015</p>
                            </footer>

                            <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> 
                            <script src="https://gitcdn.github.io/bootstrap-toggle/2.2.0/js/bootstrap-toggle.min.js"></script>
                            <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
                                <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
                                <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> 
                                <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> 
                                <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> 
                                <script src="https://cdn.socket.io/socket.io-1.3.6.js"></script>
                                <script src="/js/test.js"></script>

                            </body>
                        </html>

<强> test.js

Socket.io客户端和JQuery的其他一些内容。

jQuery(function ($) {
    var socket = io.connect();
    var $sip = $('#sip');
    socket.on('sip', function (data) {
        var sip = '';
        for (i = 0; i < data.length; i++) {
            sip += data[i] + '<br/>'
        }
        $sip.append('<h3 class="conf-head">Conference call</h3> \
                                        <div class="panel panel-default ">\
                                            <div class="panel-heading " >\
                                                <h3 class="panel-title">' + sip + '</h3>\
                                            </div>\
                                            <div class="panel-body">\
                                                <input type="checkbox" data-on="Voice" data-off="Muted" checked data-toggle="toggle" data-onstyle="success" data-offstyle="danger">\
                                                    <button class="btn btn-default kick" id="kick" data-toggle="modal" data-target="#myModal" type="submit">Kick</button>\
                                                </div>\
                                            </div>');

    });

    $('.kick').click(function () {
        $('#myInput').focus()
    });
});