Router.js: различия между версиями
Материал из support.qbpro.ru
imported>Supportadmin (Новая страница: « <nowiki>////////////////////////// ////////router.js///////// ////////////////////////// ///////А.В. Климов//////// ////////////////////////// ////////01…») |
(нет различий)
|
Текущая версия от 15:38, 4 августа 2013
//////////////////////////
////////router.js/////////
//////////////////////////
///////А.В. Климов////////
//////////////////////////
////////01.11.2012////////
//Используются модули fifo.js, net, socket.io
//////////////////////////
//Предназначен для перенаправления входящего через WebSocket (далее ws) потока
//в поток с использованием NetSocket (далее ns) для передачи заданий на исполнение.
//Наличие исполнителей (их адреса локальные (127.х.х.х) или в перспективе сетевые)
//конфигурируется через параметр (массив) workers=[].
//Выбор маршрута определяется исходя из текущей (моментальной) нагрузки workerов.
//Имеет отдельный управляющий канал ns для связи с ядром
//////////////////////////
//Принцип работы:
//При поступлении сообщения от клиента по протоколу ws генерируется стандартное
//событие 'data' в функции ws.on(). По этому событию из буфера сокета сообщение
//помещается в очередь ws_fifo_ns. Функция ns каждый цикл EventLoop проверяет
//наличие заданий в очереди (длину массива ws_fifo_ns) и в случае ненулевого
//значения, первое сообщение отправляется в ns конкретному исполнителю. Выбор
//исполнителя осуществляется по критерию нагрузки {надо сделать расчет на
//основе средневзвешенного коэффициента нагрузки, когда каждое задание имеет
//вес - а)число определяющее степеть предполагаемой (временной) загрузки процесса EventLoop
//по времени исполнения [математическая, чтение/запись в файл, чтение/запись БД]
//б) собирать статистику времени вылонения, используемой памяти и на её основе выставлять вес задания,
//что позволит избежать неправильного веса при увеличении данных в запросе к БД
//(т.н. автокорретировка)}. http://th-algoritmov.narod.ru/4.htm http://th-algoritmov.narod.ru/5.htm
//Книга Идеальный код. http://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BA%D0%BE%D0%BD_%D0%90%D0%BC%D0%B4%D0%B0%D0%BB%D0%B0
//
//////////////////////////
//Управляющий ns поток
//ns используется для мгновенного обмена информацией с ядром системы. Ядро может
//собирать статистику и устанавливать конфигурационные пераметры:
//-добавлять/убирать worker путем
var fifo= require("fifo"), //Модуль, организующий очередь FIFO
websocket = require('socket.io'), //Модуль, организующий WebSocket
netsocket = require('net'), //Модуль, организующий NetSocket
json_rpc= require('json_rpc'); //Модуль, организующий анализ и синтез формата json-rpc
var ws_fifo = new fifo(), //очередь WebSocket->fifo для входящих (от клиента) сообщений перед маршрутизацией
fifo_ws = new fifo(), //очередь для исходящих (к клиенту) сообщений fifo->WebSocket
fifo_ns = new fifo(), //очередь fifo->NetSocket для исходящих сообщений после маршрутизации
ns_fifo = new fifo(), //очередь для входящих сообщений NetSocket->fifo->WebSocket
ws = new websocket(), //создаем новый экземпляр WebSocket
ns = new netsocket(), //создаем новый экземпляр NetSocket
ns_direct = new netsocket(); //создаем новый экземпляр NetSocket (управляющий канал)
//WebSocket
ws.listen(8080); // Cтавим на прослушивание 8080-порта
ws.set('log level', 1); // Отключаем вывод полного лога - пригодится в production'е
ws.sockets.on('connection', function (socket) { // Навешиваем обработчик на подключение нового клиента
// Т.к. чат простой - в качестве ников пока используем первые 5 символов от ID сокета
//var ID = (socket.id).toString().substr(0, 5);
var ID = (socket.id).toString(); //В качестве ников пока используем ID сокета
var time = (new Date).toLocaleTimeString();
socket.json.send({'event': 'connected',
'name': ID,
'time': time});// Посылаем клиенту сообщение о том, что он успешно подключился и его имя
socket.broadcast.json.send({'event': 'userJoined',
'name': ID,
'time': time}); // Посылаем всем остальным пользователям, что подключился новый клиент и его имя
socket.on('message', function (msg) { // Навешиваем обработчик на входящее сообщение
var time = (new Date).toLocaleTimeString();
socket.json.send({'event': 'messageSent',
'name': ID,
'text': msg,
'time': time}); // Уведомляем клиента, что его сообщение успешно дошло до сервера
//socket.broadcast.json.send({'event': 'messageReceived',
// 'name': ID,
// 'text': msg,
// 'time': time}) // Отсылаем сообщение остальным участникам чата
/////////////////////////
//Здесь обработать авторизацию, занести в БД сессию
//Если ошибка уведомить клиента (вернуть error в fifo_ws в формате JSON-RPC)
/////////////////////////
/////////////////////////
//Здесь проверить валидность JSON-RPC
//Если ошибка уведомить клиента (вернуть error в fifo_ws в формате JSON-RPC)
/////////////////////////
/////////////////////////
//Проверить наличие и соответствие команды на выполнение
//Если ошибка уведомить клиента (вернуть error в fifo_ws в формате JSON-RPC)
/////////////////////////
/////////////////////////
//Здесь записать id задания(из JSON-RPC), id сокета, id клиента, id функции(для статистики), время начала в буфер.
//Из номера этой строки, id функции, параметры функции, сформировать в формате JSON-RPC задание для woker
/////////////////////////
/////////////////////////
//Здесь предать JSON-RPC запрос в fifo_ns
/////////////////////////
});
socket.on('disconnect', function() { // При отключении клиента - уведомляем остальных
var time = (new Date).toLocaleTimeString();
io.sockets.json.send({'event': 'userSplit', 'name': ID, 'time': time});
});
});
