diff options
Diffstat (limited to '')
-rw-r--r-- | lib/realtime.js | 201 |
1 files changed, 78 insertions, 123 deletions
diff --git a/lib/realtime.js b/lib/realtime.js index ca9cecd8..66a3c9c5 100644 --- a/lib/realtime.js +++ b/lib/realtime.js @@ -16,6 +16,9 @@ var moment = require('moment'); var config = require("../config.js"); var logger = require("./logger.js"); +//ot +var ot = require("./ot/index.js"); + //others var db = require("./db.js"); var Note = require("./note.js"); @@ -60,28 +63,41 @@ function secure(socket, next) { } } +function emitCheck(note) { + var out = { + updatetime: note.updatetime + }; + for (var i = 0, l = note.socks.length; i < l; i++) { + var sock = note.socks[i]; + sock.emit('check', out); + }; +} + //actions var users = {}; var notes = {}; var updater = setInterval(function () { async.each(Object.keys(notes), function (key, callback) { var note = notes[key]; - if (note.isDirty) { + if (note.server.isDirty) { if (config.debug) logger.info("updater found dirty note: " + key); - var body = LZString.decompressFromUTF16(note.body); + var body = note.server.document; var title = Note.getNoteTitle(body); title = LZString.compressToBase64(title); body = LZString.compressToBase64(body); - db.saveToDB(key, title, body, - function (err, result) {}); - note.isDirty = false; + db.saveToDB(key, title, body, function (err, result) { + if (err) return; + note.server.isDirty = false; + note.updatetime = Date.now(); + emitCheck(note); + }); } callback(); }, function (err) { if (err) return logger.error('updater error', err); }); -}, 5000); +}, 1000); function getStatus(callback) { db.countFromDB(function (err, data) { @@ -189,9 +205,6 @@ function emitRefresh(socket) { socket.emit('refresh', { owner: note.owner, permission: note.permission, - body: note.body, - otk: note.otk, - hash: note.hash, updatetime: note.updatetime }); } @@ -202,8 +215,13 @@ var isDisconnectBusy = false; var disconnectSocketQueue = []; function finishConnection(socket, notename) { - notes[notename].users[socket.id] = users[socket.id]; - notes[notename].socks.push(socket); + var note = notes[notename]; + note.users[socket.id] = users[socket.id]; + note.socks.push(socket); + note.server.addClient(socket); + note.server.setName(socket, users[socket.id].name); + note.server.setColor(socket, users[socket.id].color); + emitOnlineUsers(socket); emitRefresh(socket); @@ -260,18 +278,16 @@ function startConnection(socket) { return; } var body = LZString.decompressFromBase64(data.rows[0].content); - body = LZString.compressToUTF16(body); + //body = LZString.compressToUTF16(body); var updatetime = data.rows[0].update_time; + var server = new ot.EditorSocketIOServer(body, [], notename, ifMayEdit); notes[notename] = { owner: owner, permission: note.permission, socks: [], - body: body, - isDirty: false, users: {}, - otk: shortId.generate(), - hash: md5(body), - updatetime: moment(updatetime).valueOf() + updatetime: moment(updatetime).valueOf(), + server: server }; finishConnection(socket, notename); }); @@ -294,17 +310,18 @@ function disconnect(socket) { if (users[socket.id]) { delete users[socket.id]; } - if (notes[notename]) { - delete notes[notename].users[socket.id]; + var note = notes[notename]; + if (note) { + delete note.users[socket.id]; do { - var index = notes[notename].socks.indexOf(socket); + var index = note.socks.indexOf(socket); if (index != -1) { - notes[notename].socks.splice(index, 1); + note.socks.splice(index, 1); } } while (index != -1); - if (Object.keys(notes[notename].users).length <= 0) { - if (notes[notename].isDirty) { - var body = LZString.decompressFromUTF16(notes[notename].body); + if (Object.keys(note.users).length <= 0) { + if (note.server.isDirty) { + var body = note.server.document; var title = Note.getNoteTitle(body); title = LZString.compressToBase64(title); body = LZString.compressToBase64(body); @@ -363,20 +380,20 @@ function updateUserData(socket, user) { if (socket.request.user && socket.request.user.logged_in) { var profile = JSON.parse(socket.request.user.profile); var photo = null; - switch(profile.provider) { - case "facebook": - photo = 'https://graph.facebook.com/' + profile.id + '/picture'; - break; - case "twitter": - photo = profile.photos[0].value; - break; - case "github": - photo = 'https://avatars.githubusercontent.com/u/' + profile.id + '?s=48'; - break; - case "dropbox": - //no image api provided, use gravatar - photo = 'https://www.gravatar.com/avatar/' + md5(profile.emails[0].value); - break; + switch (profile.provider) { + case "facebook": + photo = 'https://graph.facebook.com/' + profile.id + '/picture'; + break; + case "twitter": + photo = profile.photos[0].value; + break; + case "github": + photo = 'https://avatars.githubusercontent.com/u/' + profile.id + '?s=48'; + break; + case "dropbox": + //no image api provided, use gravatar + photo = 'https://www.gravatar.com/avatar/' + md5(profile.emails[0].value); + break; } user.photo = photo; user.name = profile.displayName || profile.username; @@ -389,6 +406,29 @@ function updateUserData(socket, user) { } } +function ifMayEdit(socket, callback) { + var notename = getNotenameFromSocket(socket); + if (!notename || !notes[notename]) return; + var note = notes[notename]; + var mayEdit = true; + switch (note.permission) { + case "freely": + //not blocking anyone + break; + case "editable": + //only login user can change + if (!socket.request.user || !socket.request.user.logged_in) + mayEdit = false; + break; + case "locked": + //only owner can change + if (note.owner != socket.request.user._id) + mayEdit = false; + break; + } + callback(mayEdit); +} + function connection(socket) { //split notename from socket var notename = getNotenameFromSocket(socket); @@ -442,30 +482,6 @@ function connection(socket) { emitRefresh(socket); }); - //received client data updated - socket.on('update', function (body_) { - var notename = getNotenameFromSocket(socket); - if (!notename || !notes[notename]) return; - if (config.debug) - logger.info('SERVER received [' + notename + '] data updated: ' + socket.id); - var note = notes[notename]; - if (note.body != body_) { - note.body = body_; - note.hash = md5(body_); - note.updatetime = Date.now(); - note.isDirty = true; - } - var out = { - id: socket.id, - hash: note.hash, - updatetime: note.updatetime - }; - for (var i = 0, l = note.socks.length; i < l; i++) { - var sock = note.socks[i]; - sock.emit('check', out); - }; - }); - //received user status socket.on('user status', function (data) { var notename = getNotenameFromSocket(socket); @@ -591,67 +607,6 @@ function connection(socket) { disconnectSocketQueue.push(socket); disconnect(socket); }); - - //when received client change data request - socket.on('change', function (op) { - var notename = getNotenameFromSocket(socket); - if (!notename || !notes[notename]) return; - var note = notes[notename]; - switch (note.permission) { - case "freely": - //not blocking anyone - break; - case "editable": - //only login user can change - if (!socket.request.user || !socket.request.user.logged_in) - return; - break; - case "locked": - //only owner can change - if (note.owner != socket.request.user._id) - return; - break; - } - op = LZString.decompressFromUTF16(op); - if (op) - op = JSON.parse(op); - else - return; - if (config.debug) - logger.info('SERVER received [' + notename + '] data changed: ' + socket.id + ', op:' + JSON.stringify(op)); - switch (op.origin) { - case '+input': - case '+delete': - case '+transpose': - case 'paste': - case 'cut': - case 'undo': - case 'redo': - case 'drag': - case '*compose': - case 'case': - case '+insert': - case '+insertLine': - case '+swapLine': - case '+joinLines': - case '+duplicateLine': - case '+sortLines': - op.id = socket.id; - op.otk = note.otk; - op.nextotk = note.otk = shortId.generate(); - var stringop = JSON.stringify(op); - var compressstringop = LZString.compressToUTF16(stringop); - for (var i = 0, l = note.socks.length; i < l; i++) { - var sock = note.socks[i]; - if (config.debug) - logger.info('SERVER emit sync data out [' + notename + ']: ' + sock.id + ', op:' + stringop); - sock.emit('change', compressstringop); - }; - break; - default: - logger.info('SERVER received uncaught [' + notename + '] data changed: ' + socket.id + ', op:' + JSON.stringify(op)); - } - }); } module.exports = realtime;
\ No newline at end of file |