javascript - 如何在 socket.io 和 Node.js 中使用 Asterisk ARI

标签 javascript jquery node.js socket.io asterisk

最近开始学习 asterisk、Linux、node.js 和最近的 socket.io,以便我最终可以为 asterisk 制作实时 Web 应用程序。

因此,根据有根据的猜测,我们可以看出 Node.js 就像是 Asterisk 和 Socket 之间的中间人。但是我不知道如何通过 socket.io 将信息从 asterisk 拉到网页。

我一直在研究 socket.io 并且已经不知所措了几天如何将它们相互链接所以我可以例如记录停滞中发生的事件或在电话 session 中拉出当前通话等等在这一点上,由于 ARI 据我所知是相对较新的,因此很难弄清楚。

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

我可以通过 node.js 运行文件,调用我在 extensions.conf 文件中指定的分机,当第一个用户进入 session 时播放音乐,一旦超过 1 个用户进入则停止音乐。

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

我只需要一个简单的例子来说明如何塑造它们或使它们协同工作,就可以开始为 Asterisk 制作实时 Web 应用程序。

即使我能够以某种方式通过 socket.io 和 Node.js 将停滞事件拉出到网页。

希望你们能提供一些见解或指导,因为目前我真的很迷茫。

bridge-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>

最佳答案

因此,经过一些试验和错误后,可以通过有效合并 bridge-mixed.js 和 app.js 文件让它们协同工作。一旦完成,我就可以开始通过 ARI 客户端访问 Asterisk 方面的信息,并开始通过 socket.io 将其传递到充当 Asterisk 前端的实时 Web 应用程序。

我目前发布的代码只是将当前调用者姓名附加到网页,但它是一个基本示例,它应该是一个很好的垫脚石,看看你可以用它做什么,因为那里的信息可以很容易地开始使用JQuery 开始做所有好事....例如静音调用,桥接从 session 中踢用户。这些是目前正在做的事情,将来会更新。

我希望这对某人有帮助。

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()
    });
});

关于javascript - 如何在 socket.io 和 Node.js 中使用 Asterisk ARI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32952007/

相关文章:

javascript - Mapdispatchtoprops 没有为 props 提供功能

javascript - JWT token 签名验证 javascript

javascript - AngularJS - 无法删除小数点后的数字

java - 如何将 HTML 表数据绑定(bind)到 Spring Controller 中的 java 对象?

Javascript 停止一个事件

javascript - 对象引用在 JavaScript 内部是如何工作的

javascript - 在普通 JavaScript 中,将相对路径 + 基本 URL 转换为绝对 URL

javascript - 如何设置此输入正则表达式框需要时间?

javascript - jQuery:向下滚动和向上滚动具有幻灯片效果

node.js - Sails.js 静态 html 渲染器