运行 javascript 里面休息 api
Running javascript inside rest api
我正在研究星号。
我设法使用拨号规则呼叫外部 api。
现在我想在 api 函数中 运行 一个 javascript,因为我需要通知浏览器有人正在调用。我在想的是,我可以使用 node.js 来做到这一点。我不想使用 ajax 轮询,因为它很糟糕。
下面是有人打电话时的流程
调用 -> 触发拨号规则 -> 通过 AGI 方法调用外部 api -> 运行 javascript 内部的 websocket 事件 api -> 通知浏览器。
这可能吗?或者有更好的方法。
答案是 "yes" - 但它还取决于您要使用的 API 以及您要实现的目标。
Asterisk 具有三个 "main" API:AMI、AGI 和 ARI。 AMI和AGI已经存在了很长时间; ARI——Asterisk REST 接口——相对较新。引用 Asterisk wiki:
Not long into the project, two application programming interfaces
(APIs) were added to Asterisk: the Asterisk Gateway Interface (AGI)
and the Asterisk Manager Interface (AMI). These interfaces have
distinct purposes:
- AGI is analogous to CGI in Apache. AGI provides an interface between the Asterisk dialplan and an external program that wants to
manipulate a channel in the dialplan. In general, the interface is
synchronous - actions taken on a channel from an AGI block and do not
return until the action is completed.
- AMI provides a mechanism to control where channels execute in the dialplan. Unlike AGI, AMI is an asynchronous, event driven interface.
For the most part, AMI does not provide mechanisms to control channel
execution - rather, it provides information about the state of the
channels and controls about where the channels are executing
与 AMI 和 AGI 不同,ARI 就是让您编写自己的拨号方案应用程序。如果您对此感兴趣,我强烈建议您查看上面链接的维基页面。
您选择的 API 应基于您希望完成的任务。既然你想做一个呼叫弹出,你真的可以通过 AMI(通过监听一些事件触发器)或通过 ARI(通过让频道进入 Stasis 拨号计划应用程序,执行自定义 node.js ARI 申请)。
两个 API 都有 node.js 个库:
AMI
阿里
您说 "want to notify a browser that someone is calling",所以我认为 Web Socket 是您正在寻找的解决方案。
WebSocket is defined as a two-way communication between the servers and the clients, which mean both the parties, communicate and exchange data at the same time.
Asterisk 17 Events REST API 描述了用于事件的 WebSocket 连接,
这是在 CLI Asterisk 中生成 WebSocket 连接的 example。
这是我测试的情况:
http 服务器节点有 2 个角色:
- 是一个 WebSocket 客户端,它通过 ARI(Aterisk 休息接口)从服务器 Asterisk 获取消息。
- 是一个附加socket.io的http服务器,它向所有socket.io个客户端
通知一些信息
1. 在/etc/asterisk/ari.conf
中创建一个用户
这里我定义了一个用户'toto',密码'pass1'
2. app.js
npm 安装 websocket 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.141.235: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>Real time application</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
结果:
我正在研究星号。 我设法使用拨号规则呼叫外部 api。 现在我想在 api 函数中 运行 一个 javascript,因为我需要通知浏览器有人正在调用。我在想的是,我可以使用 node.js 来做到这一点。我不想使用 ajax 轮询,因为它很糟糕。
下面是有人打电话时的流程
调用 -> 触发拨号规则 -> 通过 AGI 方法调用外部 api -> 运行 javascript 内部的 websocket 事件 api -> 通知浏览器。
这可能吗?或者有更好的方法。
答案是 "yes" - 但它还取决于您要使用的 API 以及您要实现的目标。
Asterisk 具有三个 "main" API:AMI、AGI 和 ARI。 AMI和AGI已经存在了很长时间; ARI——Asterisk REST 接口——相对较新。引用 Asterisk wiki:
Not long into the project, two application programming interfaces (APIs) were added to Asterisk: the Asterisk Gateway Interface (AGI) and the Asterisk Manager Interface (AMI). These interfaces have distinct purposes:
- AGI is analogous to CGI in Apache. AGI provides an interface between the Asterisk dialplan and an external program that wants to manipulate a channel in the dialplan. In general, the interface is synchronous - actions taken on a channel from an AGI block and do not return until the action is completed.
- AMI provides a mechanism to control where channels execute in the dialplan. Unlike AGI, AMI is an asynchronous, event driven interface. For the most part, AMI does not provide mechanisms to control channel execution - rather, it provides information about the state of the channels and controls about where the channels are executing
与 AMI 和 AGI 不同,ARI 就是让您编写自己的拨号方案应用程序。如果您对此感兴趣,我强烈建议您查看上面链接的维基页面。
您选择的 API 应基于您希望完成的任务。既然你想做一个呼叫弹出,你真的可以通过 AMI(通过监听一些事件触发器)或通过 ARI(通过让频道进入 Stasis 拨号计划应用程序,执行自定义 node.js ARI 申请)。
两个 API 都有 node.js 个库:
AMI
阿里
您说 "want to notify a browser that someone is calling",所以我认为 Web Socket 是您正在寻找的解决方案。
WebSocket is defined as a two-way communication between the servers and the clients, which mean both the parties, communicate and exchange data at the same time.
Asterisk 17 Events REST API 描述了用于事件的 WebSocket 连接, 这是在 CLI Asterisk 中生成 WebSocket 连接的 example。
这是我测试的情况:
http 服务器节点有 2 个角色:
- 是一个 WebSocket 客户端,它通过 ARI(Aterisk 休息接口)从服务器 Asterisk 获取消息。
- 是一个附加socket.io的http服务器,它向所有socket.io个客户端 通知一些信息
1. 在/etc/asterisk/ari.conf
中创建一个用户这里我定义了一个用户'toto',密码'pass1'
2. app.js
npm 安装 websocket 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.141.235: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>Real time application</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
结果: