我正在使用星号。我设法使用Dialplan调用了一个外部api。现在,我想在该api函数中运行一个javascript,因为我需要通知浏览器有人正在呼叫。我在想,我可以使用node.js做到这一点。我不想使用Ajax轮询,因为它很糟糕。
以下是有人打电话的过程
[呼叫->触发拨号计划->通过AGI方法调用外部api->在api中运行javascript websocket事件->通知浏览器。
有可能吗?或还有更好的方法。
答案是“是”-但这还取决于您要使用的API以及您要完成的工作。
星号具有三个“主要” API:AMI,AGI和ARI。 AMI和AGI已经存在很长时间了。 ARI-Asterisk REST接口-相对较新。引用Asterisk wiki:
不久后进入项目,两个应用程序编程接口(API)已添加到Asterisk:Asterisk网关接口(AGI)和星号管理器界面(AMI)。这些接口有不同的目的:
- AGI类似于Apache中的CGI。 AGI在Asterisk拨号计划和想要在拨号方案中操作频道。一般来说,界面是同步-从AGI块对通道执行的操作,但不返回,直到操作完成。
- AMI提供了一种机制来控制通道在拨号计划中的执行位置。与AGI不同,AMI是异步的,事件驱动的接口。在大多数情况下,AMI不提供控制信道的机制执行-而是提供有关状态的信息通道以及有关通道执行位置的控件
与AMI和AGI不同,ARI的全部目的是让您编写自己的Dialplan应用程序。如果您对此感兴趣,我强烈建议您查看上面链接的Wiki页面。
您选择的API应该基于您要完成的任务。由于您要进行呼叫弹出,因此您确实可以通过AMI(通过侦听某些事件触发器)或通过ARI(通过使通道进入Stasis拨号计划应用程序,执行自定义node.js ARI应用程序)来实现)。
两个API都有node.js库:
AMI
ARI
您说过“想通知浏览器有人正在呼叫”,所以我认为Web Socket是您正在寻找的解决方案。
WebSocket被定义为服务器和客户端之间的双向通信,这意味着双方都同时通信和交换数据。
Asterisk 17 Events REST API描述了用于事件的WebSocket连接,这是在CLI星号中生成WebSocket连接的example。
http服务器节点具有2个角色:
这里我用密码“ pass1”定义了一个用户“ toto”
npm install websoket socket.io
var http = require('http'); var fs = require('fs'); // Loading the index.html file displayed to the client (browser) var httpserver = http.createServer(function(req, res) { fs.readFile('./index.html', 'utf-8', function(error, content) { res.writeHead(200, {"Content-Type": "text/html"}); res.end(content); }); }); // create a ws connection to the server asterisk const WebSocket = require('ws'); const ws_client = new WebSocket('ws://192.168.8.162:8088/ari/events?api_key=toto:pass1&app=hello&subscribeAll=true'); // ws_client listens to the event 'error' for getting errors // when the server asterisk has some socket connection problems ws_client.on('error',function error(error){ console.log(error); }) // create an instance socket.io attached to http server var io_httpserver = require('socket.io')(httpserver); //listens all clients which connect to the socket 'mysocket', //in this case we have only one client (sokcet.io_client_1) in index.html io_httpserver.sockets.on('connection', function (mysocket) { // ws_client listens to the event 'message' for getting data of the server asterisk ws_client.on('message',function show(data){ //send data to all clients which listen to the custom event 'titi' mysocket.emit('titi',data); }) }); httpserver.listen(8080);
3. index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Socket.io</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" /> </head> <body> <h1>Communication with socket.io !</h1> <table id="one" class="table table-dark"> <thead> <tr> <th scope="col">date</th> <th scope="col">endpoints</th> <th scope="col">states</th> </tr> </thead> <tbody> </tbody> </table> <script src="https://cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.js"></script> <script> var tab = document.getElementById('one'); var sokcet.io_client_1 = io.connect('http://localhost:8080'); sokcet.io_client_1.on('titi', function(data) { console.log(data) var obj = JSON.parse(data); if(obj.type=="DeviceStateChanged"){ var date = obj.timestamp.split('.')[0].replace("T", " "); tab.insertAdjacentHTML('beforeend', '<td>'+date+'</td><td>'+obj.device_state.name+'</td><td>'+obj.device_state.state+'</td>'); } }) </script> </body> </html>
最终加载app.js:
node app.js