Commit b38ea9b9 authored by sergey's avatar sergey

use code @zignd for AGI server

parent 6962e9c5
...@@ -2,14 +2,10 @@ ...@@ -2,14 +2,10 @@
[![Build Status](https://travis-ci.org/antirek/ding-dong.svg?branch=master)](https://travis-ci.org/antirek/ding-dong) [![Build Status](https://travis-ci.org/antirek/ding-dong.svg?branch=master)](https://travis-ci.org/antirek/ding-dong)
Create AGI server with ding-dong. Use with Asterisk for fast telephony apps. node.js lib for Fast AGI (Asterisk Gateway Interface) server
[Fork of node-agi](http://github.com/brianc/node-agi) [Fork of node-agi](http://github.com/brianc/node-agi)
stable version 0.1.1
unstable version 0.1.5
Use ding-dong Use ding-dong
============= =============
...@@ -21,38 +17,32 @@ Use ding-dong ...@@ -21,38 +17,32 @@ Use ding-dong
[lcr-finder](http://github.com/antirek/lcr-finder) - least cost router for Asterisk [lcr-finder](http://github.com/antirek/lcr-finder) - least cost router for Asterisk
## Install ## Install
``` ```
npm install ding-dong [--save] npm install ding-dong
``` ```
## Usage
### Write app.js and run it
`````javascript `````javascript
var AGIServer = require('ding-dong'); const AGIServer = require('ding-dong');
var handler = function (context) { const handler = (context) => {
context.onEvent('variables') context.onEvent('variables')
.then(function (vars) { .then((vars) => {
return context.streamFile('beep'); return context.streamFile('beep');
}) })
.then(function (result) { .then((result) => {
return context.setVariable('RECOGNITION_RESULT', 'I\'m your father, Luc'); return context.setVariable('RECOGNITION_RESULT', 'I\'m your father, Luc');
}) })
.then(function (result) { .then((result) => {
return context.end(); return context.close();
}); });
}; };
var agi = new AGIServer(handler); var agi = new AGIServer(handler, {port: 3000});
agi.start(3000); agi.init();
````` `````
...@@ -63,9 +53,6 @@ agi.start(3000); ...@@ -63,9 +53,6 @@ agi.start(3000);
exten = > 1000,1,AGI(agi://localhost:3000) exten = > 1000,1,AGI(agi://localhost:3000)
````` `````
### And call to 1000 and view asterisk output. Profit!
## API ## API
see [API.md](API.md) see [API.md](API.md)
......
const AGIServer = require('./../lib/index'); const AGIServer = require('./../lib/index');
const handler = function(context) { const handler = (context) => {
context.onEvent('variables') context.onEvent('variables')
.then(function(vars) { .then((vars) => {
console.log('vars', vars); console.log('vars', vars);
return context.streamFile('beep'); return context.streamFile('beep');
}) })
.then(function(result) { .then((result) => {
return context.setVariable( return context.setVariable(
'RECOGNITION_RESULT', 'I\'m your father, Luc'); 'RECOGNITION_RESULT', 'I\'m your father, Luc');
}) })
.then(function(result) { .then((result) => {
return context.end(); return context.end();
}) })
.fail(console.log); .fail(console.log);
}; };
const agi = new AGIServer(handler, {debug: true}); const agi = new AGIServer(handler, {
agi.start(3007); debug: true,
port: 3007
});
agi.init()
\ No newline at end of file
...@@ -5,7 +5,7 @@ const commands = require('./command'); ...@@ -5,7 +5,7 @@ const commands = require('./command');
// base context // base context
const Context = function(stream, loggerOptions = {}) { const Context = function(conn, loggerOptions = {}) {
EventEmitter.call(this); EventEmitter.call(this);
const consoleDecorator = function(arrow, data) { const consoleDecorator = function(arrow, data) {
...@@ -17,9 +17,10 @@ const Context = function(stream, loggerOptions = {}) { ...@@ -17,9 +17,10 @@ const Context = function(stream, loggerOptions = {}) {
this.debug = loggerOptions.debug; this.debug = loggerOptions.debug;
this.conn = conn;
this.stream = new Readable(); this.stream = new Readable();
this.stream.setEncoding('utf8'); this.stream.setEncoding('utf8');
this.stream.wrap(stream); this.stream.wrap(this.conn);
this.state = state.init; this.state = state.init;
this.msg = ''; this.msg = '';
...@@ -116,7 +117,8 @@ Context.prototype.send = function(msg, cb) { ...@@ -116,7 +117,8 @@ Context.prototype.send = function(msg, cb) {
this.stream.write(msg); this.stream.write(msg);
}; };
Context.prototype.end = function() { Context.prototype.close = function() {
this.conn.destroy();
this.stream.end(); this.stream.end();
return Promise.resolve(); return Promise.resolve();
}; };
......
const EventEmitter = require('events');
const Context = require('./context'); const Context = require('./context');
const agi = function(handler, optionsIn) { /**
const options = optionsIn || {}; *
*/
class AgiServer extends EventEmitter {
/**
*
* @param {*} handler
* @param {*} options
*/
constructor(handler, options) {
super();
const settings = { options = options || {};
this.options = {
port: options.port || 3000, port: options.port || 3000,
debug: options.debug || false, debug: options.debug || false,
logger: options.logger || false, logger: options.logger || false,
host: options.host, host: options.host,
}; };
const handle = function(stream) { this.handler = handler;
const context = new Context(stream, {
debug: settings.debug, this.server = require('net').createServer((connection) => {
logger: options.logger, const context = new Context(connection, {
debug: this.options.debug,
logger: this.options.logger,
}); });
handler(context); this.handler(context);
}; });
}
const start = function(portIn, hostIn) { /**
const port = portIn || settings.port; *
const host = hostIn || settings.host; */
return require('net').createServer(handle).listen(port, host); init() {
}; this.server.on('error', (err) => {
this.emit('error', new Error('Internal TCP server error'));
});
this.server.on('close', () => this.emit('close'));
return { this.server.listen(this.options.port, this.options.host, () => {
start: start, console.log('agi server on', this.options.port, 'listen');
}; });
}; }
/**
* @return {Promise}
*/
close() {
return new Promise((resolve, reject) => {
this.server.close((err) => {
if (err) {
return reject(err);
} else {
return resolve();
}
});
});
}
}
module.exports = agi; module.exports = AgiServer;
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
"author": "Sergey Dmitriev <serge.dmitriev@gmail.com>", "author": "Sergey Dmitriev <serge.dmitriev@gmail.com>",
"name": "ding-dong", "name": "ding-dong",
"description": "Write AGI-server quickly! (AGI - Asterisk Gateway Interface)", "description": "Write AGI-server quickly! (AGI - Asterisk Gateway Interface)",
"version": "0.1.7", "version": "0.2.0",
"license": "MIT",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/antirek/ding-dong.git" "url": "git://github.com/antirek/ding-dong.git"
...@@ -13,12 +14,12 @@ ...@@ -13,12 +14,12 @@
"lint-fix": "eslint --fix ." "lint-fix": "eslint --fix ."
}, },
"dependencies": { "dependencies": {
"expect.js": "^0.3.1",
"readable-stream": "^2.3.0" "readable-stream": "^2.3.0"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^5.16.0", "eslint": "^5.16.0",
"eslint-config-google": "^0.12.0", "eslint-config-google": "^0.12.0",
"expect.js": "^0.3.1",
"memorystream": "^0.3.0", "memorystream": "^0.3.0",
"mocha": "6.1.4" "mocha": "6.1.4"
} }
......
const MemoryStream = require('memorystream'); const MemoryStream = require('memorystream');
const Agi = require('./../lib'); const AgiServer = require('./../lib');
const expect = require('expect.js'); const expect = require('expect.js');
const Context = require('./../lib/context'); const Context = require('./../lib/context');
const state = require('./../lib/state'); const state = require('./../lib/state');
...@@ -526,19 +526,22 @@ describe('Context', function() { ...@@ -526,19 +526,22 @@ describe('Context', function() {
}); });
}); });
describe('agi#createServer', function() { describe('AgiServer#createServer', function() {
it('returns instance of net.Server', function() { it('returns instance of net.Server', function() {
const net = require('net'); const net = require('net');
const server = (new Agi()).start(3000); const agiServer = new AgiServer(() => {});
expect(server instanceof net.Server).ok(); expect(agiServer.server instanceof net.Server).ok();
}); });
it('invokes callback when a new connection is established', function(done) { it('invokes callback when a new connection is established', function(done) {
const server = new Agi(function(context) { const agiServer = new AgiServer(function(context) {
expect(context instanceof Context); expect(context instanceof Context);
done(); done();
}).start(3001); }, {
port: 3001,
});
agiServer.init();
server.emit('connection', new MemoryStream()); agiServer.server.emit('connection', new MemoryStream());
}); });
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment