Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 29.03.2016, 07:50
Новичок на форуме
Отправить личное сообщение для stonecone Посмотреть профиль Найти все сообщения от stonecone
 
Регистрация: 29.03.2016
Сообщений: 3

помогите с асинхронными событиями nodejs+websockets+библиотечка nami
Добрый день!
Не нашел на сайте раздела для новичков, поэтому пишу сюда.
В общем задача сгенерировать звонок от оператора на астериске.
Взял nodejs + websockets + nami (https://github.com/marcelog/Nami

т.е. структура такая:

[WS-Client] --- [Node.js + WS + NAMI] --- [Asterisk AMI]

я склепал тестовый myserver.js для node и вот тут столкнулся с так сказать архитектурной проблемой
код прилагаю
var logger = require(__dirname + "/node_modules/nami/node_modules/log4js").getLogger('Nami.App');
var http = require('http');
var WebSocketServer = require('ws');
var namiLib = require(__dirname + '/node_modules/nami/src/nami.js');
var call = require('./call');
var clients = {};

var namiConfig = {
    host: '192.168.1.2',
    port: '5038',
    username: 'amiuser',
    secret: 'amipass'
};

var nami = new namiLib.Nami(namiConfig);

nami.logger.setLevel("OFF");
process.on('SIGINT', function() {
    nami.close();
    process.exit();
});

nami.on('namiConnectionClose', function (data) {
    logger.debug('Reconnecting...');
    setTimeout(function () { nami.open(); }, 5000);
});

nami.on('namiLoginIncorrect', function () {
    logger.fatal("Invalid Credentials");
    process.exit();
});

nami.on('namiEvent', function (event) {
    //logger.debug('Got Event: ' + util.inspect(event));
    //if (event.get("ActionID") !== undefined) {
        logger.debug(util.inspect(event));
    //}
    //logger.debug("hehe");
});
nami.on('namiInvalidPeer', function (data) {
    logger.fatal("Invalid AMI Salute. Not an AMI?");
    process.exit();
});

nami.on('namiConnected', function(event){
    console.log("nami connected");
});
nami.open();

var webSocketServer = new WebSocketServer.Server({
    port: 8081
});

webSocketServer.on('connection', function (ws) {
    ws.on('message', function (message) {
        msg = JSON.parse(message);
        var newcall = new call.Call(ws);
        clients[newcall.actionid] = newcall;
        if ( msg.action === "call" && phoneIsValid(msg.phonenumber) && opNumIsValid(msg.operatornumber) ) {
            var action = new namiLib.Actions.Originate();
            action.channel = "Local/" + msg.operatornumber + "@local-calls";
            action.callerid = msg.phonenumber;
            action.priority = "1";
            action.timeout = "30000";
            action.context = "callcenter";
            action.exten = msg.phonenumber;
            action.ActionID = newcall.actionid;
            action.async = "yes";
            nami.send(action, function (response) {

            });
            respmsg = {
                type: "status",
                status: "Calling " + msg.phonenumber
            };
            ws.send(JSON.stringify(respmsg));
        }
        ws.on('close', function() {
            delete clients[newcall.actionid];
        });
    });
});

var server = http.createServer(function (request, response){
    var headers = request.headers;
    var method = request.method;
    var url = request.url;
    var body = [];
    request.on('error', function (err) {
        console.error(err);
    }).on('data', function (chunk) {
        body.push(chunk);
    }).on('end', function () {
        body = Buffer.concat(body).toString();
    });

    response.on('error', function(err){
        console.error(err);
    });

    response.statusCode = 200;
    response.setHeader('Content-Type', 'application/json');

    var responseBody = {
        headers: headers,
        method: method,
        url: url,
        body: body
    };

    response.write(JSON.stringify(responseBody));
    response.end();

}).listen(8085);

function phoneIsValid(phone) {
    if ( phone ) {
        regex = /^89\d{9}$/;
        return phone.match(regex);
    }
    return false;
}

// operator number must be 1XX or 2XX
function opNumIsValid(phone) {
    if ( phone ) {
        return phone.match(/^[12]{1}[0-9]{2}$/);
    }
    return false;
}

в общем я не пойму следующее - у меня есть
webSocketServer.on('connection', function (ws) {});

и внутри я навешиваю на события действия. Прекрасно.
Также есть всевозможные
nami.on({});

в них я навешиваю действия при получении чего-то от астериска.
А как мне навешать в nami.on передать что-то в вебсокет, ведь вебсокет в отдельном объекте. В общем я похоже даже не могу правильно словами выразить )))
Как мне повешать в
nami.on('namiEvent', function(event){});

отправку в вебсокет? Фильтры я уж догадаюсь сделать.
Я не понимаю как мне связать эти два разных объекта.
Как правильно это сделать по структуре, объясните пожалуйста.
Я новичок, но не полный нуль.
Спасибо!
Ответить с цитированием
  #2 (permalink)  
Старый 01.04.2016, 02:27
Аспирант
Отправить личное сообщение для Max Power Посмотреть профиль Найти все сообщения от Max Power
 
Регистрация: 15.12.2015
Сообщений: 83

> Я новичок, но не полный нуль.
> Спасибо!

Да пожалуйста! А что вы сделали чтобы локализовать проблему? Вангую - ни один нормальный чел не полезет в 130-страничный листинг с локальной проблемой и какой-то спец либой, которую из русскоговорящих знают двое.
Ответить с цитированием
  #3 (permalink)  
Старый 17.04.2016, 20:15
Новичок на форуме
Отправить личное сообщение для ramauf Посмотреть профиль Найти все сообщения от ramauf
 
Регистрация: 16.04.2016
Сообщений: 3

ты решил вопрос? у меня то же самое, поясню короче
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
function handler (req, res) {
/*тут разный код*/
}
io.on('connection', function (socket) {
/*тут разный код*/
});
var timer = setInterval(function(){
/*как отсюда вызвать socket.emit?*/
});
Ответить с цитированием
  #4 (permalink)  
Старый 17.04.2016, 20:16
Новичок на форуме
Отправить личное сообщение для ramauf Посмотреть профиль Найти все сообщения от ramauf
 
Регистрация: 16.04.2016
Сообщений: 3

ты решил вопрос? у меня то же самое, поясню короче
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
function handler (req, res) {
/*тут разный код*/
}
io.on('connection', function (socket) {
/*тут разный код*/
});
var timer = setInterval(function(){
/*как отсюда вызвать socket.emit?*/
});



да и еще при этом онлайн может быть 100 юзверей, т.е. заводить таймер внутри io.on('connection'.... разумно ли? 0_о

помогите решить!!!!!

Последний раз редактировалось ramauf, 17.04.2016 в 20:34.
Ответить с цитированием
  #5 (permalink)  
Старый 18.04.2016, 10:35
Новичок на форуме
Отправить личное сообщение для stonecone Посмотреть профиль Найти все сообщения от stonecone
 
Регистрация: 29.03.2016
Сообщений: 3

ramauf,
нет не решил еще
взял Стояна Стефанова "Javascript шаблоны", читаю про шаблоны "Посредник" и "Прокси", думаю где-то здесь.
Это какая-то стандартная несложная схема должна быть.
Просто форумчанин который мне ответил до тебя не понял моего вопроса. Как разберусь отпишу сюда обязательно.
Ответить с цитированием
  #6 (permalink)  
Старый 19.04.2016, 10:43
Новичок на форуме
Отправить личное сообщение для stonecone Посмотреть профиль Найти все сообщения от stonecone
 
Регистрация: 29.03.2016
Сообщений: 3

в общем я сделал так:
1. создал объект call (звонок), это по сути связка "JS клиент подключенный к websocket" (храню в свойстве сокет) ---- "id звонка который запросил клиент" (храню в свойствах actionid и uniqueid)
2. создал массив clients, куда складываю объекты из п. 1.
3. при инициации клиентом звонка (мне клиент не нужен на стадии подключения, я с ним не собираюсь общаться помимо звонков) создаю объект из п. 1 и кладу его в массив клиентов. При отключении клиента удаляю объект звонка из массива. Тут все инициируется со стороны вебсокетов, со стороны js клиента.
4. при окончании звонка (их неск вариантов) отправляю статус JS клиенту и опять же удаляю объект звонка из массива. А тут вызов происходит со стороны AMI, т.е. есть со стороны астериска. Всё.
у тебя это будет выглядеть как-то так
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
// создай и подключи класс Клиент вот тут Илья все классно объясняет: [url]http://www.youtube.com/watch?v=g740J-RyoR4&index=5&list=PLDyvV36pndZFWfEQpNixIHVvp191Hb3Gg[/url] 
var сlient = require(./client);
// массив с твоими клиентами, можно тут хранить имена, сокеты и айди если надо, сам нарисуй объект со свойствами которые тебе нужны
clients = [];
function handler (req, res) {
/*тут разный код*/
}
io.on('connection', function (socket) {
 // при подключении создаешь объект Клиент и кладешь его в массив клиентов
 client = new client.Client(ws);
/*тут разный код*/
});
var timer = setInterval(function(){
/*как отсюда вызвать socket.emit?*/
// тут шлешь своим клиентам сообщения если я тебя правильно понял
clients.forEach(function(client, i, clients){
    msg = {
        type: "status",
        status: "originatefailed"
    };
    ws.send(JSON.stringify(msg));
});
});


правда у тебя socket.io, я использовал ws, но суть та же - нужно хранилище клиентов-сокетов
на лучшее решение не претендую, могут быть ошибки в коде, но идея думаю ясна
Ответить с цитированием
  #7 (permalink)  
Старый 19.04.2016, 19:32
Новичок на форуме
Отправить личное сообщение для ramauf Посмотреть профиль Найти все сообщения от ramauf
 
Регистрация: 16.04.2016
Сообщений: 3

точно точно, посмарел код на стороннем двиге и тоже пришел к выводу, что надо заводить глобальную переменную и туда складывать, пасиб за подсказку!
Ответить с цитированием
Ответ


Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите разобраться с событиями и jquery prowoke jQuery 0 09.12.2010 11:40