Продолжаем писать простенький чат на TCP-сокетах и заодно знакомиться с вариантами хранения данных приложения Node.js. Переходим к MongoDB. Прежде чем приступить к созданию кода нам потребуется создать так называемую capped collection - коллекцию ограниченного размера, для того, чтобы хранить в ней сообщения нашего чата в ограниченном количестве.
Таким образом мы создадим структуру данных по имени очередь. Но обо всем по порядку.
Для начала не забываем скачать бинарники MongoDB и запустить mongod:
Запускаем в консоли mongo shell и в базе данных по умолчанию test создаем коллекцию ограниченную размером 20 документов - сообщений нашего чата:
- db.createCollection('messages', {capped: true, size: 1000000, max: 20});
Установим MondoDB Native Driver:
- npm install mongodb
Подготовительная часть завершена, переходим к кодингу. Начнем с сервера - файл server.js.
Обернем код создания сервера в функцию обратного вызова подключения к базе данных test.
В случае успешного подключения в процессе создании объекта message - модели данных - в функцию-конструктор будем отправлять полученный в результате подключения объект db:
Редактируем код модели данных - файл message.js.
Конструктор объекта модели получает от сервера объект db - базу данных test - откуда получает коллекцию messages, с которой затем осуществляет операции вставки - this.data.insert(), а также извлечения - this.data.find() сообщений нашего чата, предлагая для этого все тот же интерфейс - insert() и get():
Сохраняем изменения, запускаем сервер, подключаем одного клиента, второго, третьего...
Консоль сервера в этот момент выглядит примерно так:
Убедимся еще раз в том, что сообщения нашего чата сохраняются - в консоли, в которой запущен mongo shell вытащим все документы коллекции messages:
- db.messages.find().pretty()
Похоже все в елочку. Наш код вполне справляется со своей задачей с помощью MondoDB Native Driver: сохраняет сообщения чата и извлекает их из коллекции messages.
На сегодня все. В следующей серии рассмотрим вариант с использованием Mongoose. Продолжение следует...
Таким образом мы создадим структуру данных по имени очередь. Но обо всем по порядку.
Для начала не забываем скачать бинарники MongoDB и запустить mongod:
Запускаем в консоли mongo shell и в базе данных по умолчанию test создаем коллекцию ограниченную размером 20 документов - сообщений нашего чата:
- db.createCollection('messages', {capped: true, size: 1000000, max: 20});
Установим MondoDB Native Driver:
- npm install mongodb
Подготовительная часть завершена, переходим к кодингу. Начнем с сервера - файл server.js.
Обернем код создания сервера в функцию обратного вызова подключения к базе данных test.
В случае успешного подключения в процессе создании объекта message - модели данных - в функцию-конструктор будем отправлять полученный в результате подключения объект db:
var net = require('net');
var PubSub = require('./pubsub'),
pubsub = new PubSub;
var Message = require('./message'),
MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/test', function(err, db) {
if(err) throw err;
console.log("--- connected to database ---");
var message = new Message(db);
net.createServer(function(socket) {
socket.setEncoding('utf8');
console.log('--- socket connected ---\nfrom: %s', socket.remoteAddress + ':' + socket.remotePort);
pubsub.emit('join', socket, function() {
message.get(null, function(err, data) {
if(err) return socket.write(err);
socket.write('\n' + data);
});
});
socket.on('data', function(data) {
data = data.replace(/\r\n$/, '');
console.log('--- socket data ---\n%s', data);
message.insert(this, data, function(err, data) {
if(err) return socket.write(err);
pubsub.emit('broadcast', socket, data);
});
});
socket.on('close', function() {
console.log('--- socket closed ---');
pubsub.emit('leave', this);
});
socket.on('end', function() {
console.log('--- socket end ---');
pubsub.emit('leave', this);
});
socket.on('error', function(e) {
console.log('--- server error ---\ncode: %s', e.code);
});
}).listen(8124, function() {
console.log('Chamber of Secrets is opened on port %d...', this.address()['port']);
});
});
Редактируем код модели данных - файл message.js.
Конструктор объекта модели получает от сервера объект db - базу данных test - откуда получает коллекцию messages, с которой затем осуществляет операции вставки - this.data.insert(), а также извлечения - this.data.find() сообщений нашего чата, предлагая для этого все тот же интерфейс - insert() и get():
module.exports = function(db, len) {
this.len = len || 100; // длина сообщения по умолчанию - 100 символов
this.data = db.collection('messages');
this.insert = function(client, data, cb) {
if(data.length > this.len) {
cb('Too much information!');
return;
}
data = {data: data, from: client['_id'], ts: Date.now()};
this.data.insert(data, function (err, result) {
if(err) return cb('--- error inserting data ---');
cb(false, createMessage(data));
});
}
this.get = function(n, cb) {
var i = n || 5; // количество сообщений по умолчанию - 5 штук
this.data.find().sort('$natural', -1).limit(i).toArray(function(err, items) {
if(err) return cb('--- error getting data ---');
cb(false, items.map(function(msg) {
return createMessage(msg);
}).reverse().join('\n'));
});
}
}
function createMessage(msg) {
return new Date(msg.ts).toLocaleTimeString() + ' ' + msg.from + ' >>> ' + msg.data;
}
Сохраняем изменения, запускаем сервер, подключаем одного клиента, второго, третьего...
Консоль сервера в этот момент выглядит примерно так:
Убедимся еще раз в том, что сообщения нашего чата сохраняются - в консоли, в которой запущен mongo shell вытащим все документы коллекции messages:
- db.messages.find().pretty()
Похоже все в елочку. Наш код вполне справляется со своей задачей с помощью MondoDB Native Driver: сохраняет сообщения чата и извлекает их из коллекции messages.
На сегодня все. В следующей серии рассмотрим вариант с использованием Mongoose. Продолжение следует...







Комментариев нет:
Отправить комментарий
Комментарий будет опубликован после модерации