玩nodebb有些日子了。以前用的是v0.4.1版本,一直用着还不错。但有朋友反应发帖时不能使用快捷键很麻烦,因此想加一个插件nodebb-plugin-shortcuts。可是使用插件后,论坛不能启动,看了看最新提交是在7天前。猜测多是nodebb新版本修改了一些文件,插件作了适应性修改,因此想把nodebb升级到最新的v0.4.3版本。升级过程很顺畅。以前也升过一次,可是由于有些问题,就回退了。今天顺便解决一下问题,学习学习。javascript
如今的问题是右上角的登陆状态有问题。css
正常的状态:html
用chrome开发者工具查看右上角的元素属性,获得一个比较有特色的元素id名logged-in-menu
,而后做为关键字在文件中搜索前端
在public目录下的文件通常都是在客户端引用的。以tpl结尾的是模板文件。多了一个.app.js.swp是由于我正在用vim编辑它。java
打开app.js后发现了这个函数:node
function updateOnlineStatus(uid) { socket.emit('user.isOnline', uid, function(err, data) { $('#logged-in-menu #user_label #user-profile-link>i').attr('class', 'fa fa-circle status ' + data.status); }); }
猜测这个函数使用socket.io与后台通讯更新了用户的登陆状态。 因而在浏览器模拟了一下动做,发现data确实能获取用户的登陆状态。可是这个函数只是改变了一下用户在线或不在线的提示颜色。jquery
绿色就是在线,黑色就是离线。看来问题不是这里,再找。git
nodebb的核心客户端js文件叫作nodebb.min.js。但是在项目里find,没有这个文件。因而猜测多是动态生成的,做为关键词搜索了下github
最下面的两个是服务端js文件,看名字应该是元变量的设置和路由。查看src/routes/meta.jsajax
<!-- lang: js --> "use strict"; ... meta = require('../meta'), ... function sendMinifiedJS(req, res, next) { return res.type('text/javascript').send(meta.js.cache); } function sendStylesheet(req, res, next) { res.type('text/css').send(200, meta.css.cache); } module.exports = function(app, middleware, controllers) { app.get('/stylesheet.css', sendStylesheet); app.get('/nodebb.min.js', sendMinifiedJS); ... };
确实是在src/meta.js中对静态js、css文件作了压缩并缓存到了各属性的cache变量中。
<!-- lang: js --> ... Meta.js = { cache: undefined, prepared: false, scripts: [ 'vendor/jquery/js/jquery.js', ... 'src/app.js', ... ], minFile: 'nodebb.min.js', ... minify: function(minify) { // Prepare js for minification/concatenation var minifier = this.minifierProc = fork('minifier.js'); minifier.on('message', function(payload) { if (payload.action !== 'error') { winston.info('[meta/js] Compilation complete'); Meta.js.cache = payload.data; minifier.kill(); } else { winston.error('[meta/js] Could not compile client-side scripts!'); winston.error('[meta/js] ' + payload.error.message); minifier.kill(); process.exit(); } }); this.prepare(function() { minifier.send({ action: minify ? 'js.minify' : 'js.concatenate', scripts: Meta.js.scripts }); }); }, ... };
能够看到public/src/app.js也在压缩之列。
再去看看public/src/app.js吧。发现前几行就定义了一个全局变量,里边记录了用户的基本信息,能够试试。
如下是个人app变量:
username,uid居然都为空!确定是有问题的。
再去nodebb官方社区登陆了下试试,果真有值!
继续查看app.js。nodebb为了作到实时通讯,大量使用了socket.io。
app变量的值在前端是在socket.on('event:connect')时被赋予的。
刚才个人论坛里app变量有空值多是由于升级过程当中没有停机,session管理有异常致使的。
因而跟代码到了src/socket.io/indexjs的io.sockets.on('connection')。
开始我觉得db.sessionStore.get(sessionID,function...)中的sessionID不对,由于我观察redis中的sessino都是以sess:做为前缀的。可是打印此处的sessionID并无带sess:,还自觉得是地加了sess:,但是仍是不行。看了connect-redis(一个专门用redis作sessionStore的项目)的源码才发现,在对redis进行get操做前,默认加了前缀sess:。
查了这么久都没什么收获,看来得换个方向了。
除了右上角的登陆状态显示有异常外,论坛右侧的状态统计功能也失效了。因而乎跟了一下代码,发现如下语句报undefined。代码位于node_modules/nodebb-widget-essentials/public/templates/forumstats.tpl。
// public/templates/forumstats.tpl ajaxify.register_events([ 'user.count', 'meta.getUsageStats', 'user.getActiveUsers' ]);
这个代码属于nodebb-widget-essentials。因而去github上看了一下是否有更新。发现上面代码用如下代码替换了。
$(window).on('action:ajaxify.start', function(ev) { socket.removeListener('user.count', updateUserCount); socket.removeListener('meta.getUsageStats', updateUsageStats); socket.removeListener('user.getActiveUsers', updateActiveUsers); });
忽然想到,本次升级的这些异常是否由于只对nodebb自己进行了升级,而忽略了各类依赖包和插件的升级呢?因而乎...npm update
。
重启应用...问题消失...
呵呵...居然是由于这么简单的缘由...虽然是个低级错误,但仍是有必要注意一下的。顺便赞一下nodebb的松耦合设计,自己只保留了不多的骨架而把比较独立的功能都作成了各类widget、plugin,从而在具体功能的实现和个性化上及其地方便。
在升级成功以后,npm install nodebb-plugin-shortcuts
便可安装快捷键,支持了包括发帖等大量的快捷键。