写在前面:欢迎大家与我交流讨论任何关于聊天服务开发有关的问题!!!
在阅读本文之前,你需要对pomelo的基本知识有所了解,可参考:
注:这里所介绍的聊天服务是集成在Web应用中的一个模块,不是独立的聊天系统
在这里对用
JWTToken
进行简单的介绍:用户在登陆后获取到服务器返回的token
(可理解为身份令牌
),下一次请求时带上这个令牌进行身份验证,验证成功才可访问。且token
有过期时间,在一定时间以内有效,超期后需重新登陆。
不了解JWTToken
的可以到这里看看:JWTToken简介
注:以pomelo为基础的聊天服务器是基于websocket长连接的,因此只有第一次连接的请求是发送http请求(三次握手),后续调用根据route路由,故在例子中将token作为请求参数传到服务端进行身份验证,若有其他的更好的处理方法,欢迎交流讨论。
JWTToken
组成header
)、载荷(payload
)、签证(signature
)。a.声明类型(jwt) b.声明加密使用的算法
(通常直接使用HmacSHA256)。如:{‘type’:‘JWT’, ‘alg’: ‘HS256’}" . "
连接headerStr
payloadStr
headerStr + '.' + payloadStr
经过header中声明的加密方式进行secret组合加密后的字符串,记为 sigStr
JWTToken = headerStr + ‘.’ + payloadStr + ‘.’ + sigStr
注:JWTtoken 各部分JSON对象中的属性顺序不可调换
Filter.js(game-server/app/servers/chat/filter/)
module.exports = function(){
return new Filter();
}
var Filter = function(){};
// 前置filter,在请求之前进行处理
Filter.prototype.before = function(msg, session, next){
// 获取请求的参数:content表示发送的消息,token即为请求的token
var content = msg.content;
var token = msg.token;
// 进行token验证,判断token是否正确以及是否过期
if(validate(token)){
// 验证成功,对content进行处理,处理后参数会传到对应接口
msg.content = content.replace('fuck', '****');
// next() 表示filter处理结束,下一步会转到对应请求的handler中
next();
}
// token验证失败,在msg中放置错误信息,如:
msg.code = 500;
msg.errorMsg = 'token错误或token过期';
next();
}
// 后置filter,在请求结束后进行处理
Filter.prototype.before = function(msg, session, next){
// 根据业务需要进行添加处理,略...
}
创建好filter后,在app.js中引入Filter.js,并如下配置:
var pomelo = require('pomelo');
var routeUtil = require('./app/util/routeUtil');
/**
* Init app for client.
*/
var app = pomelo.createApp();
app.set('name', 'chatofpomelo');
// 对所有的connector服务器进行配置
app.configure('production|development', 'connector', function(){
app.set('connectorConfig',
{
connector : pomelo.connectors.hybridconnector,
heartbeat : 3,
useDict : true,
useProtobuf : true,
closeTimeout : 60 * 1000,
});
});
// 对所有的gate服务器进行配置
app.configure('production|development', 'gate', function(){
app.set('connectorConfig',
{
connector : pomelo.connectors.hybridconnector,
useProtobuf : true,
closeTimeout : 60 * 1000,
});
});
// 引入创建的Filter.js
var Filter = require('./app/servers/chat/filter/Filter');
// app configure,该配置表示在所有的服务器中都生效
app.configure('production|development', function() {
// route configures
app.route('chat', routeUtil.chat);
// 使用Filter,before表示前置,after表示后置
app.before(Filter);
});
// start app
app.start();
process.on('uncaughtException', function(err) {
console.error(' Caught exception: ' + err.stack);
});
注:在此filter中,把处理的结果在真正的业务处理接口,即chat/handler中进行判断,错误则直接返回到前端服务器。(未找到直接在filter中返回错误到前端服务器的方式,如有更好的方案,欢迎交流学习)
pomelo通过封装
log4js
,形成了pomelo-logger
这个组件,因而使用日志记录时需引入这个组件。为了能够更好的理解log4js的处理,在本文中对直接使用log4js进行介绍。
// 引入log4js对象
var log4js = require('log4js');
// 配置日志内容
log4js.configure({
appenders: {
console: {
type: "console"
},
dateFile: {
type: "dateFile",
// 生成日志的保存路径,该路径表示日志保存到项目目录下的logs文件夹
filename: "logs/LogFile",
pattern: "-yyyy-MM-dd.log",
category: "log_date",
encoding: 'utf-8',
alwaysIncludePattern: true
}
},
categories: {
dateFile: {
appenders: ['dateFile'], level: 'error'
},
default: {
appenders: ['console', 'dateFile'], level: 'all'
}
}
});
var dateFile = log4js.getLogger('log_date')
module.exports = dateFile
使用时可通过: var log = require(‘创建的log4js.js文件’);
通过log.error();log.info();log.warn()
等输入不同级别的日志信息。
关于log4js的详细介绍,可查看:log4js及其API
运行环境:AWS云服务器(EC2)
步骤:
1.搭建环境:安装node(建议使用nvm进行安装)、安装python、安装pomelo(npm install pomelo -g)
2.拉取代码:git clone https://github.com/NetEase/chatofpomelo.git
(以chatofpomelo为例)
3.运行项目目录下的npm-install.sh脚本安装相关依赖
注:若遇到安装权限问题,可对相关错误的文件及文件夹使用(sudo chown -R 当前登录用户名 filePath)修改权限
4.pomelo start -e production -D 运行服务(-e为选择环境,-D表示后台运行)
问题:
1.启动后访问报错 ParserIncomingMessage is not a constructor.
解决:node版本太高,选择较低的版本重装后再从步骤3开始。
注:本人使用的node版本为 v6.11.2,报错的node版本为 v10.x.x
2.关于host地址的设置(暂未使用pomelo的集群配置,故host均为同一IP)
在game-server/config
下的master.json
和servers.json
中,将其中的host
改为对应服务器的公网IP
.
以上是对pomelo使用的一些记录,若有任何错误的地方,欢迎指正,也希望能和大家一起交流学习,共同进步。