pomelo入门

本文详细介绍了如何使用Pomelo游戏服务器框架实现聊天功能,包括编码方式、WebSocket连接建立、请求发送流程以及后台处理机制。通过实例分析,展示了Pomelo在游戏开发中作为高效服务器解决方案的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一直觉得没有读过什么node.js的框架,觉得很遗憾。。。好了,从今天开始,读pomelo的源代码。。。

网易开源的游戏服务器框架,看介绍。。应该还不错。。先看看吧。。。

从它给的聊天的例子来开始吧。。。比较简单。。。无非就是web端通过websocket发送数据到服务器,然后服务器再广播给同房间的人就ok了。。。

我们先来看看pomelo发送数据的格式吧,也就是它的encode方法:

 //用于将发送的数据编码为pomelo的格式,其中id为客户端提供,用于区别待会消息的确认
 //route可以理解为要将数据发送到什么地方去
 //msg就是实际要发送的数据,json格式
 //前5个int是头部,头部的前4个是id,第5个表示数据表示route的长度,然后剩下的保存要发送的数据
Protocol.encode = function(id,route,msg){
    var msgStr = JSON.stringify(msg);
    if (route.length>255) { throw new Error('route maxlength is overflow'); }
    //强类型数组
    var byteArray = new Uint16Array(HEADER + route.length + msgStr.length);
    var index = 0;
    byteArray[index++] = (id>>24) & 0xFF;
    byteArray[index++] = (id>>16) & 0xFF;
    byteArray[index++] = (id>>8) & 0xFF;
    byteArray[index++] = id & 0xFF;
    byteArray[index++] = route.length & 0xFF;
    //先把他们穿华为unicode码
    for(var i = 0;i<route.length;i++){
        byteArray[index++] = route.charCodeAt(i);
    }
    for (var i = 0; i < msgStr.length; i++) {
        byteArray[index++] = msgStr.charCodeAt(i);
    }
    //将这些unicode码转化为字符串
    return bt2Str(byteArray,0,byteArray.length);
};
其实encode的过程还是相对比较简单的吧,分为头部,route和数据3个部分,如图:


这里位的单位是16位的无符号int(新的版本的javascript引入了强类型数组),先将数据全部转化为了unicode码,然后再将数据转化为字符串。。。

接下来来看看pomelo在web端怎么进行操作(pomeloclient.js)。。。先来看看init函数:

  pomelo.init = function(params, cb){
    pomelo.params = params;
    params.debug = true;
    var host = params.host;
    var host = "121.199.40.246";   //主机地址
    var port = params.port;   //主机端口

    var url = 'ws://' + host;
    if(port) {
      url +=  ':' + port;
    }
//进行websocket的链接
    socket = io.connect(url, {'force new connection': true, reconnect: false});

    socket.on('connect', function(){
      console.log('[pomeloclient.init] websocket connected!');
      if (cb) {
        cb(socket);
      }
    });

    socket.on('reconnect', function() {
      console.log('reconnect');
    });
    //如果收到了数据,那么调用processMessage来处理这些数据
    socket.on('message', function(data){
      if(typeof data === 'string') {
        data = JSON.parse(data);
      }
      if(data instanceof Array) {
        processMessageBatch(pomelo, data);
      } else {
        processMessage(pomelo, data);
      }
    });

    socket.on('error', function(err) {
      console.log(err);
    });

    socket.on('disconnect', function(reason) {
      pomelo.emit('disconnect', reason);
    });
  };
代码很容易就能懂,就是建立websocket的连接,然后设置一些监听函数,这里我把host的ip改成了自己服务器的ip地址,不然的话使用的是127.0.0.1,那么就只能部署在本地了。。。

接下来是比较重要的request功能,也就是用于向pomelo后台发送数据

//用于向pomelo后台发送数据,route是要发送到的地方
//接下来的参数可以是要发送的数据,以及消息确认的回调函数
  pomelo.request = function(route) {
    if(!route) {
      return;
    }
    var msg = {};
    var cb;
    arguments = Array.prototype.slice.apply(arguments);
    if(arguments.length === 2){
      if(typeof arguments[1] === 'function'){
        cb = arguments[1];
      }else if(typeof arguments[1] === 'object'){
        msg = arguments[1];
      }
    }else if(arguments.length === 3){
      msg = arguments[1];
      cb = arguments[2];
    }
    msg = filter(msg,route);
    id++;   //当前发送的数据的id
    callbacks[id] = cb;   //当发送的这个数据有返回的时候,用这个回调函数来处理
    var sg = Protocol.encode(id,route,msg);   //将数据转化为规定的格式
    socket.send(sg);
  };
这里参数可以有3个,第一个是route,也就是要发送到的地方,后面两个参数是要发送的数据,可以带一个毁掉函数,用于发送的数据收到了后台的确认之后执行。。。看起来像是消息服务器的pub的过程。。。

嗯,接下来来看看web端是如何调用request来发送数据的吧:

	//按了回车按钮之后,执行的函数
	$("#entry").keypress(function(e) {
		var route = "chat.chatHandler.send";  //要发送到的route
		var target = $("#usersList").val();
		if(e.keyCode != 13 /* Return */ ) return;
		var msg = $("#entry").attr("value").replace("\n", "");
		if(!util.isBlank(msg)) {
			pomelo.request(route, {
				rid: rid,   //room的id
				content: msg,   
				from: username,    
				target: target
			}, function(data) {
				$("#entry").attr("value", ""); // clear the entry field.
				if(target != '*' && target != username) {
					addMessage(username, target, msg);
					$("#chatHistory").show();
				}
			});
		}
	});
这里我们可以看到了这个route的值是什么了。。。这种route的方式让我想起来了ruby on rails,直接与后台的文件夹对应起来就好了。。。


貌似后台的route也就是按照这样的方式来组织的吧。。。还算挺方便的。。。

接下来我们来看看后台chatHandler的send方法的定义吧:

handler.send = function(msg, session, next) {
	var rid = session.get('rid');   //获取当前的房间的id
	var username = session.uid.split('*')[0];
	var channelService = this.app.get('channelService');
	var param = {
		route: 'onChat',
		msg: msg.content,
		from: username,
		target: msg.target
	};
	channel = channelService.getChannel(rid, false);   //用于向当前房间广播的channel

	//the target is all users
	if(msg.target == '*') {
		channel.pushMessage(param);
	}
	//the target is specific user
	else {
		var tuid = msg.target + '*' + rid;
		var tsid = channel.getMember(tuid)['sid'];
		channelService.pushMessageByUids(param, [{
			uid: tuid,
			sid: tsid
		}]);
	}
	next(null, {
		route: msg.route
	});
};
msg就是客户端传过来的数据,另外还有session,这个应该是pomelo来维护的吧。。。


好了,这篇文章略微看了看pomelo提供的chat的例子的web端是如何给后台发送数据的。。。下一篇在来看看后台到底是怎么运行的吧。。。。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值