#推荐
Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

2024-10-01 13,808

情怀麻将网络通讯

要点:

  1. express 框架的基本用法
  2. socket.io 的原理与使用方法
  3. Creator 源码阅读的高效技巧
  4. 解析达达麻将的游客登录机制

达达麻将服务器配置

  1. express:Node.js 中的轻量级高效 Web 框架,达达麻将使用 HTTP 协议构建的 Web 服务器。
  2. socket.io:Node.js 的网络模块,将网络通讯封装为事件模式。
  3. account_server:负责账号验证的服务器,基于 express 框架 (1 个实例)。
  4. hall_server:大厅服务器,使用 express 作为通讯框架 (2 个实例)。
  5. mj_server:游戏服务器,采用 socket.io 与 express 结合的网络架构 (1 个实例)。
  6. 客户端:通过调用 API 函数进行 HTTP 请求。

express 安装步骤

  1. 通过 npm 安装 express 模块:
bash
npm install express
Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio
2:使用 express 创建一个应用实例:
const express = require("express");  
const app = express();  

// 启动服务器,监听 8090 端口  
app.listen(8090, () => {  
    console.log("服务器已启动,监听端口 8090");  
});  

// 使用 HTTP 协议的 GET 请求来发送数据  
app.get("/login", (req, res) => {  
    res.send("----ok----");  
});  

// 启动 Node.js 服务器并运行 Express 框架  
// 执行命令:node webserver.js  

// 在浏览器中输入以下地址进行访问测试  
// http://127.0.0.1:8090/login  
// 页面将显示:----ok----  

Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

3: 配置好 webserver 的端口;

const express = require("express");  
const app = express();  

// 监听 8090 端口  
app.listen(8090, () => {  
    console.log("服务器正在监听端口 8090...");  
});  

// 定义 GET 请求,用于响应 /login 路由  
app.get("/login", (req, res) => {  
    res.send("----ok----");  

    // 处理带参数的请求,并在控制台输出参数内容  
    console.log("收到请求参数:", req.query);  
});  

Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

4配置静态资源路径

5设置 HTTP GET 请求服务

6配置 HTTP POST 请求服务

7检查达达麻将 account 服务器的整体结构


//G:\..\..\js_ddmj\server\server\account_server\app.js
 
var db = require('../utils/db');
var configs = require(process.argv[2]);
 
//init db pool.
//连接数据库(初始化)
db.init(configs.mysql());
 
//
//获得账号服务器account_server的配置文件
var config = configs.account_server();
var as = require('./account_server');
as.start(config);
 
//启动服务器
var dapi = require('./dealer_api');
dapi.start(config);
 
 
-------------------------------------------
//G:\..\..\js_ddmj\server\server\account_server\account_server.js
 
var crypto = require('../utils/crypto');
var express = require('express');
var db = require('../utils/db');
var http = require("../utils/http");
 
//生成一个基于express的对象,来完成web服务,作为web服务器
//通过http协议,和客户端交互数据
var app = express();
var hallAddr = "";
 
function send(res,ret){
	var str = JSON.stringify(ret);
	res.send(str)
}
 
var config = null;
 
//启动account server账号服务器
exports.start = function(cfg){
	config = cfg;
	hallAddr = config.HALL_IP  + ":" + config.HALL_CLIENT_PORT;
	app.listen(config.CLIENT_PORT);
	console.log("account server is listening on " + config.CLIENT_PORT);
}
 
 
//----函数功能----
//等待客户端的请求,URL----register注册
app.get('/register',function(req,res){
 
//等待客户端的请求,URL----get_version获取版本
app.get('/get_version',function(req,res){
 
 
//等待客户端的请求,URL----get_serverinfo获取服务器信息
app.get('/get_serverinfo',function(req,res){
 
//等待客户端的请求,URL----guest游客登录
app.get('/guest',function(req,res){
 
//等待客户端的请求,URL----微信登录的获取auth
app.get('/auth',function(req,res){
 
//微信登录相关信息
var appInfo = {
 
//微信登录获取access_token
function get_access_token(code,os,callback){
 
//微信登录,获取state_info
function get_state_info(access_token,openid,callback){
 
//微信登录,获取wechat_auth
app.get('/wechat_auth',function(req,res){
 
//等待客户端的请求,URL----base_info获取基础信息
app.get('/base_info',function(req,res){
 
------------------------------------------------------------------------------
//G:\..\..\js_ddmj\server\server\configs_local.js
var HALL_IP = "127.0.0.1";
var HALL_CLIENT_PORT = 9001;
var HALL_ROOM_PORT = 9002;
 
var ACCOUNT_PRI_KEY = "^&*#$%()@";
var ROOM_PRI_KEY = "~!@#$(*&^%$&";
 
var LOCAL_IP = 'localhost';
 
exports.mysql = function(){
	return {
		HOST:'127.0.0.1',
		USER:'root',
		PSWD:'123456',
		DB:'dd_mj',
		PORT:3306,
	}
}
 
//账号服配置
exports.account_server = function(){
	return {
		CLIENT_PORT:9000,
		HALL_IP:HALL_IP,
		HALL_CLIENT_PORT:HALL_CLIENT_PORT,
		ACCOUNT_PRI_KEY:ACCOUNT_PRI_KEY,
		
		//
		DEALDER_API_IP:LOCAL_IP,
		DEALDER_API_PORT:12581,
		VERSION:'20161227',
		APP_WEB:'http://fir.im/2f17',
	};
};
G:\..\..\js_ddmj\server\server\hall_server\app.js
var client_service = require("./client_service");
var room_service = require("./room_service");
 
var configs = require(process.argv[2]);
//获取大厅的配置文件
var config = configs.hall_server();
 
var db = require('../utils/db');
//初始化数据库
db.init(configs.mysql());
 
//启动客户端的大厅web服务器的请求
client_service.start(config);
//启动客户端的房间web服务器的请求
room_service.start(config);
 
-----------------------------------------------------------
G:\..\..\js_ddmj\server\server\hall_server\client_service.js
 
//http协议下的数据交互
var app = express();
var config = null;
 
//配置好响应请求:登录到大厅服务器;
app.get('/login',function(req,res){
 
//创建一个用户
app.get('/create_user',function(req,res){
 
//创建一个房间
app.get('/create_private_room',function(req,res){
 
//进入一个房间
app.get('/enter_private_room',function(req,res){
 
//获取历史记录
app.get('/get_history_list',function(req,res){
 
//获取游戏房间
app.get('/get_games_of_room',function(req,res){
 
//获取游戏房间详细信息
app.get('/get_detail_of_game',function(req,res){
 
//获取玩家状态
app.get('/get_user_status',function(req,res){
 
//获取消息
app.get('/get_message',function(req,res){
 
//查询服务器是否在线
app.get('/is_server_online',function(req,res){
 
//启动函数
exports.start = function($config){
	config = $config;
	app.listen(config.CLEINT_PORT);
	console.log("client service is listening on port " + config.CLEINT_PORT);
};
 
//设置跨域访问
app.all('*', function(req, res, next) {
	res.header("Access-Control-Allow-Origin", "*");
	res.header("Access-Control-Allow-Headers", "X-Requested-With");
	res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
	res.header("X-Powered-By",' 3.2.1');
	res.header("Content-Type", "application/json;charset=utf-8");
	next();
});
 
 
 
-----------------------------------------------------------
G:\..\..\js_ddmj\server\server\hall_server\room_service.js
 
//注册
app.get('/register_gs',function(req,res){
 
//启动函数
exports.start = function($config){
	config = $config;
	app.listen(config.ROOM_PORT,config.FOR_ROOM_IP);
	console.log("room service is listening on " + config.FOR_ROOM_IP + ":" + config.ROOM_PORT);
};
 
 
 
-----------------------------------------------------------
G:\..\..\js_ddmj\server\server\majiang_server\app.js
 
 
 
var http_service = require("./http_service");
var socket_service = require("./socket_service");
 
//从配置文件获取服务器信息
var configs = require(process.argv[2]);
var config = configs.game_server();
 
var db = require('../utils/db');
db.init(configs.mysql());
 
//开启HTTP服务
http_service.start(config);
 
//开启外网SOCKET服务
socket_service.start(config);
 
//require('./gamemgr');
 
 
 
G:\..\..\js_ddmj\server\server\majiang_server\http_service.js
//获取服务器信息
app.get('/get_server_info',function(req,res){
 
//创建房间
app.get('/create_room',function(req,res){
 
//加入房间
app.get('/enter_room',function(req,res){
 
//ping检查
app.get('/ping',function(req,res){
 
//房间是否允许中
app.get('/is_room_runing',function(req,res){
 
 
//向大厅服定时心跳
function update(){
	if(lastTickTime + config.HTTP_TICK_TIME < Date.now()){
		lastTickTime = Date.now();
		gameServerInfo.load = roomMgr.getTotalRooms();
		http.get(config.HALL_IP,config.HALL_PORT,"/register_gs",gameServerInfo,function(ret,data){
			if(ret == true){
				if(data.errcode != 0){
					console.log(data.errmsg);
				}
				
				if(data.ip != null){
					serverIp = data.ip;
				}
			}
			else{
				//
				lastTickTime = 0;
			}
		});
 
		var mem = process.memoryUsage();
		var format = function(bytes) {  
              return (bytes/1024/1024).toFixed(2)+'MB';  
        }; 
		//console.log('Process: heapTotal '+format(mem.heapTotal) + ' heapUsed ' + format(mem.heapUsed) + ' rss ' + format(mem.rss));
	}
}
 
 
//启动函数
exports.start = function($config){
	config = $config;
 
	//
	gameServerInfo = {
		id:config.SERVER_ID,
		clientip:config.CLIENT_IP,
		clientport:config.CLIENT_PORT,
		httpPort:config.HTTP_PORT,
		load:roomMgr.getTotalRooms(),
	};
 
	setInterval(update,1000);
	app.listen(config.HTTP_PORT,config.FOR_HALL_IP);
	console.log("game server is listening on " + config.FOR_HALL_IP + ":" + config.HTTP_PORT);
};
socket.io
1:socket.io把网络的接受数据,看作是网络事件,发送端发送一个事件,接收端接受这个事件;

2: 接受的时候可以带着数据,这样,就能够进行数据交换;

3: socket.io能支持tcp, ws两种,开发人员不用关心,这个也就是为什么他会在node.js里流行的模型;

4: socket.io的简单使用: 监听事件,触发事件;

5: 达达麻将服务器的socket.io的代码;

6: 有人收就有人发,要善于查代码,来看逻辑;

G:\..\..\js_ddmj\server\server\majiang_server\socket_service.js
 
//启动服务
exports.start = function(config,mgr){
	io = require('socket.io')(config.CLIENT_PORT);
	//监听是否有客户端连接进来,如果有客户连接进来就会调用这个函数
	//为这个客户创建一个socket通道
	io.sockets.on('connection',function(socket){
		//监听一个事件,然后data,客户端发送过来的数据
		//数据使用的是json协议的编码,来进行数据交换;底层发送json文本;
		socket.on('login',function(data){
			//转成json格式数据
			data = JSON.parse(data);
			if(socket.userId != null){
				//已经登陆过的就忽略
				return;
			}
 
 
 
 
//emit发送一个事件
socket.emit('login_result',{errcode:2,errmsg:"login failed. invalid sign!"});
 
socket.io----事件的模式,事件+事件数据;监听事件,事件数据;使用emit来发送;
 
//json协议的编码:转成json格式数据
data = JSON.parse(data);
 
----------------------------------------------------------------------------------
var crypto = require('../utils/crypto');
var db = require('../utils/db');
 
var tokenMgr = require('./tokenmgr');
var roomMgr = require('./roommgr');
var userMgr = require('./usermgr');
var io = null;
 
//启动服务
exports.start = function(config,mgr){
	io = require('socket.io')(config.CLIENT_PORT);
	//监听是否有客户端连接进来,如果有客户连接进来就会调用这个函数
	//为这个客户创建一个socket通道
	io.sockets.on('connection',function(socket){
		//监听一个事件,然后data,客户端发送过来的数据
		socket.on('login',function(data){
			data = JSON.parse(data);
			if(socket.userId != null){
				//已经登陆过的就忽略
				return;
			}
			var token = data.token;
			var roomId = data.roomid;
			var time = data.time;
			var sign = data.sign;
 
			console.log(roomId);
			console.log(token);
			console.log(time);
			console.log(sign);
 
			
			//检查参数合法性
			if(token == null || roomId == null || sign == null || time == null){
				console.log(1);
				socket.emit('login_result',{errcode:1,errmsg:"invalid parameters"});
				return;
			}
			
			//检查参数是否被篡改
			var md5 = crypto.md5(roomId + token + time + config.ROOM_PRI_KEY);
			if(md5 != sign){
				console.log(2);
				//emit发送一个事件
				socket.emit('login_result',{errcode:2,errmsg:"login failed. invalid sign!"});
				return;
			}
			
			//检查token是否有效
			if(tokenMgr.isTokenValid(token)==false){
				console.log(3);
				socket.emit('login_result',{errcode:3,errmsg:"token out of time."});
				return;
			}
			
			//检查房间合法性
			var userId = tokenMgr.getUserID(token);
			var roomId = roomMgr.getUserRoom(userId);
 
			userMgr.bind(userId,socket);
			socket.userId = userId;
 
			//返回房间信息
			var roomInfo = roomMgr.getRoom(roomId);
			
			var seatIndex = roomMgr.getUserSeat(userId);
			roomInfo.seats[seatIndex].ip = socket.handshake.address;
 
			var userData = null;
			var seats = [];
			for(var i = 0; i < roomInfo.seats.length; ++i){
				var rs = roomInfo.seats[i];
				var online = false;
				if(rs.userId > 0){
					online = userMgr.isOnline(rs.userId);
				}
 
				seats.push({
					userid:rs.userId,
					ip:rs.ip,
					score:rs.score,
					name:rs.name,
					online:online,
					ready:rs.ready,
					seatindex:i
				});
 
				if(userId == rs.userId){
					userData = seats[i];
				}
			}
 
			//通知前端
			var ret = {
				errcode:0,
				errmsg:"ok",
				data:{
					roomid:roomInfo.id,
					conf:roomInfo.conf,
					numofgames:roomInfo.numOfGames,
					seats:seats
				}
			};
			socket.emit('login_result',ret);
 
			//通知其它客户端
			userMgr.broacastInRoom('new_user_comes_push',userData,userId);
			
			socket.gameMgr = roomInfo.gameMgr;
 
			//玩家上线,强制设置为TRUE
			socket.gameMgr.setReady(userId);
 
			socket.emit('login_finished');
 
			if(roomInfo.dr != null){
				var dr = roomInfo.dr;
				var ramaingTime = (dr.endTime - Date.now()) / 1000;
				var data = {
					time:ramaingTime,
					states:dr.states
				}
				userMgr.sendMsg(userId,'dissolve_notice_push',data);	
			}
		});
 
		socket.on('ready',function(data){
			var userId = socket.userId;
			if(userId == null){
				return;
			}
			socket.gameMgr.setReady(userId);
			userMgr.broacastInRoom('user_ready_push',{userid:userId,ready:true},userId,true);
		});
 
		//换牌
		socket.on('huanpai',function(data){
			if(socket.userId == null){
				return;
			}
			if(data == null){
				return;
			}
 
			if(typeof(data) == "string"){
				data = JSON.parse(data);
			}
 
			var p1 = data.p1;
			var p2 = data.p2;
			var p3 = data.p3;
			if(p1 == null || p2 == null || p3 == null){
				console.log("invalid data");
				return;
			}
			socket.gameMgr.huanSanZhang(socket.userId,p1,p2,p3);
		});
 
		//定缺
		socket.on('dingque',function(data){
			if(socket.userId == null){
				return;
			}
			var que = data;
			socket.gameMgr.dingQue(socket.userId,que);
		});
 
		//出牌
		socket.on('chupai',function(data){
			if(socket.userId == null){
				return;
			}
			var pai = data;
			socket.gameMgr.chuPai(socket.userId,pai);
		});
		
		//碰
		socket.on('peng',function(data){
			if(socket.userId == null){
				return;
			}
			socket.gameMgr.peng(socket.userId);
		});
		
		//杠
		socket.on('gang',function(data){
			if(socket.userId == null || data == null){
				return;
			}
			var pai = -1;
			if(typeof(data) == "number"){
				pai = data;
			}
			else if(typeof(data) == "string"){
				pai = parseInt(data);
			}
			else{
				console.log("gang:invalid param");
				return;
			}
			socket.gameMgr.gang(socket.userId,pai);
		});
		
		//胡
		socket.on('hu',function(data){
			if(socket.userId == null){
				return;
			}
			socket.gameMgr.hu(socket.userId);
		});
 
		//过  遇上胡,碰,杠的时候,可以选择过
		socket.on('guo',function(data){
			if(socket.userId == null){
				return;
			}
			socket.gameMgr.guo(socket.userId);
		});
		
		//聊天
		socket.on('chat',function(data){
			if(socket.userId == null){
				return;
			}
			var chatContent = data;
			userMgr.broacastInRoom('chat_push',{sender:socket.userId,content:chatContent},socket.userId,true);
		});
		
		//快速聊天
		socket.on('quick_chat',function(data){
			if(socket.userId == null){
				return;
			}
			var chatId = data;
			userMgr.broacastInRoom('quick_chat_push',{sender:socket.userId,content:chatId},socket.userId,true);
		});
		
		//语音聊天
		socket.on('voice_msg',function(data){
			if(socket.userId == null){
				return;
			}
			console.log(data.length);
			userMgr.broacastInRoom('voice_msg_push',{sender:socket.userId,content:data},socket.userId,true);
		});
		
		//表情
		socket.on('emoji',function(data){
			if(socket.userId == null){
				return;
			}
			var phizId = data;
			userMgr.broacastInRoom('emoji_push',{sender:socket.userId,content:phizId},socket.userId,true);
		});
		
		//语音使用SDK不出现在这里
		
		//退出房间
		socket.on('exit',function(data){
			var userId = socket.userId;
			if(userId == null){
				return;
			}
 
			var roomId = roomMgr.getUserRoom(userId);
			if(roomId == null){
				return;
			}
 
			//如果游戏已经开始,则不可以
			if(socket.gameMgr.hasBegan(roomId)){
				return;
			}
 
			//如果是房主,则只能走解散房间
			if(roomMgr.isCreator(userId)){
				return;
			}
			
			//通知其它玩家,有人退出了房间
			userMgr.broacastInRoom('exit_notify_push',userId,userId,false);
			
			roomMgr.exitRoom(userId);
			userMgr.del(userId);
			
			socket.emit('exit_result');
			socket.disconnect();
		});
		
		//解散房间
		socket.on('dispress',function(data){
			var userId = socket.userId;
			if(userId == null){
				return;
			}
 
			var roomId = roomMgr.getUserRoom(userId);
			if(roomId == null){
				return;
			}
 
			//如果游戏已经开始,则不可以
			if(socket.gameMgr.hasBegan(roomId)){
				return;
			}
 
			//如果不是房主,则不能解散房间
			if(roomMgr.isCreator(roomId,userId) == false){
				return;
			}
			
			userMgr.broacastInRoom('dispress_push',{},userId,true);
			userMgr.kickAllInRoom(roomId);
			roomMgr.destroy(roomId);
			socket.disconnect();
		});
 
		//解散房间
		socket.on('dissolve_request',function(data){
			var userId = socket.userId;
			console.log(1);
			if(userId == null){
				console.log(2);
				return;
			}
 
			var roomId = roomMgr.getUserRoom(userId);
			if(roomId == null){
				console.log(3);
				return;
			}
 
			//如果游戏未开始,则不可以
			if(socket.gameMgr.hasBegan(roomId) == false){
				console.log(4);
				return;
			}
 
			var ret = socket.gameMgr.dissolveRequest(roomId,userId);
			if(ret != null){
				var dr = ret.dr;
				var ramaingTime = (dr.endTime - Date.now()) / 1000;
				var data = {
					time:ramaingTime,
					states:dr.states
				}
				console.log(5);
				userMgr.broacastInRoom('dissolve_notice_push',data,userId,true);
			}
			console.log(6);
		});
 
		socket.on('dissolve_agree',function(data){
			var userId = socket.userId;
 
			if(userId == null){
				return;
			}
 
			var roomId = roomMgr.getUserRoom(userId);
			if(roomId == null){
				return;
			}
 
			var ret = socket.gameMgr.dissolveAgree(roomId,userId,true);
			if(ret != null){
				var dr = ret.dr;
				var ramaingTime = (dr.endTime - Date.now()) / 1000;
				var data = {
					time:ramaingTime,
					states:dr.states
				}
				userMgr.broacastInRoom('dissolve_notice_push',data,userId,true);
 
				var doAllAgree = true;
				for(var i = 0; i < dr.states.length; ++i){
					if(dr.states[i] == false){
						doAllAgree = false;
						break;
					}
				}
 
				if(doAllAgree){
					socket.gameMgr.doDissolve(roomId);					
				}
			}
		});
 
		socket.on('dissolve_reject',function(data){
			var userId = socket.userId;
 
			if(userId == null){
				return;
			}
 
			var roomId = roomMgr.getUserRoom(userId);
			if(roomId == null){
				return;
			}
 
			var ret = socket.gameMgr.dissolveAgree(roomId,userId,false);
			if(ret != null){
				userMgr.broacastInRoom('dissolve_cancel_push',{},userId,true);
			}
		});
 
		//断开链接
		socket.on('disconnect',function(data){
			var userId = socket.userId;
			if(!userId){
				return;
			}
			var data = {
				userid:userId,
				online:false
			};
 
			//通知房间内其它玩家
			userMgr.broacastInRoom('user_state_push',data,userId);
 
			//清除玩家的在线信息
			userMgr.del(userId);
			socket.userId = null;
		});
		
		socket.on('game_ping',function(data){
			var userId = socket.userId;
			if(!userId){
				return;
			}
			//console.log('game_ping');
			socket.emit('game_pong');
		});
	});
 
	console.log("game server is listening on " + config.CLIENT_PORT);	
};
游客登陆源码分析
1:学会搜索;

2: creator从节点触发找脚本;



客户端发送数据:

cc.vv.http.sendRequest



启动场景:
G:\..\..\js_ddmj\ddmj_20161230\client\assets\resources\scenes\loading.fire
 
 
通过场景来寻找对应的JS脚本,如上图;
 
 
 
cc.vv 的出处在此:
G:\..\..\js_ddmj\ddmj_20161230\client\assets\scripts\components\LoadingLogic.js
 
    initMgr:function(){
        cc.vv = {};
        var UserMgr = require("UserMgr");
        cc.vv.userMgr = new UserMgr();
        
        var ReplayMgr = require("ReplayMgr");
        cc.vv.replayMgr = new ReplayMgr();
        
        cc.vv.http = require("HTTP");
        cc.vv.global = require("Global");
        cc.vv.net = require("Net");
        
        var GameNetMgr = require("GameNetMgr");
        cc.vv.gameNetMgr = new GameNetMgr();
        cc.vv.gameNetMgr.initHandlers();
        
        var AnysdkMgr = require("AnysdkMgr");
        cc.vv.anysdkMgr = new AnysdkMgr();
        cc.vv.anysdkMgr.init();
        
        var VoiceMgr = require("VoiceMgr");
        cc.vv.voiceMgr = new VoiceMgr();
        cc.vv.voiceMgr.init();
        
        var AudioMgr = require("AudioMgr");
        cc.vv.audioMgr = new AudioMgr();
        cc.vv.audioMgr.init();
        
        var Utils = require("Utils");
        cc.vv.utils = new Utils();
        
        cc.args = this.urlParse();
    },

数据驱动场景,依据场景定位相应的 JS 脚本文件;
cc.vv的出处:

Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

游客登录流程中,关联的是 Login.js 文件;
Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketioCocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

服务器消息处理:

Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

成功之后走self.login();流程

login:function(){
        var self = this;
        var onLogin = function(ret){
            if(ret.errcode !== 0){
                console.log(ret.errmsg);
            }
            else{
                if(!ret.userid){
                    //jump to register user info.
                    cc.director.loadScene("createrole");
                }
                else{
                    console.log(ret);
                    self.account = ret.account;
        			self.userId = ret.userid;
        			self.userName = ret.name;
        			self.lv = ret.lv;
        			self.exp = ret.exp;
        			self.coins = ret.coins;
        			self.gems = ret.gems;
                    self.roomData = ret.roomid;
                    self.sex = ret.sex;
                    self.ip = ret.ip;
        			cc.director.loadScene("hall");
                }
            }
        };
        cc.vv.wc.show("正在登录游戏");
        cc.vv.http.sendRequest("/login",{account:this.account,sign:this.sign},onLogin);
    },

将登录请求发送至 hall_serverclient_service.js 文件:

javascript
cc.vv.http.sendRequest("/login", { account: this.account, sign: this.sign
Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

db.get_user_data(account, function(data) {

调用 utils 目录下 db.js 中的 exports.get_user_data = function(account, callback) { 来查找玩家数据,并从数据库中执行相应的查询操作。

Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

接着根据该玩家的 UserID 来判断其是否在游戏房间中,

通过 db.get_room_id_of_user(data.userid, function(roomId) { 进行房间ID的查询操作;

Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

若房间不存在或玩家已不在房间内,则清理相应的数据,并返回登录成功消息。

javascript
http.send(res, 0, "ok", ret);
Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

当账号 ID 不存在时,跳转到创建角色界面;若已有玩家信息,则直接跳转至 hall 场景,并发送登录 hall 的请求。

javascript
cc.director.loadScene("createrole"); // 进入创建角色界面
cc.director.loadScene("hall"); // 进入大厅场景
cc.vv.http.sendRequest("/login", { account: this.account, sign: this.sign }, onLogin); // 发送登录大厅的请求

创建角色场景及其关联的 JS 代码:

 

Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio


cc.Class({
    extends: cc.Component,
 
    properties: {
        inputName:cc.EditBox,
        // foo: {
        //    default: null,
        //    url: cc.Texture2D,  // optional, default is typeof default
        //    serializable: true, // optional, default is true
        //    visible: true,      // optional, default is true
        //    displayName: 'Foo', // optional
        //    readonly: false,    // optional, default is false
        // },
        // ...
    },
    
    onRandomBtnClicked:function(){
        var names = [
            "上官",
            "欧阳",
            "东方",
            "端木",
            "独孤",
            "司马",
            "南宫",
            "夏侯",
            "诸葛",
            "皇甫",
            "长孙",
            "宇文",
            "轩辕",
            "东郭",
            "子车",
            "东阳",
            "子言",
        ];
        
        var names2 = [
            "雀圣",
            "赌侠",
            "赌圣",
            "稳赢",
            "不输",
            "好运",
            "自摸",
            "有钱",
            "土豪",
        ];
        var idx = Math.floor(Math.random() * (names.length - 1));
        var idx2 = Math.floor(Math.random() * (names2.length - 1));
        this.inputName.string = names[idx] + names2[idx2];
    },
 
    // use this for initialization
    onLoad: function () {
        if(!cc.sys.isNative && cc.sys.isMobile){
            var cvs = this.node.getComponent(cc.Canvas);
            cvs.fitHeight = true;
            cvs.fitWidth = true;
        }
        this.onRandomBtnClicked();
    },
 
    onBtnConfirmClicked:function(){
        var name = this.inputName.string;
        if(name == ""){
            console.log("invalid name.");
            return;
        }
        console.log(name);
        cc.vv.userMgr.create(name);
    }
    // called every frame, uncomment this function to activate update callback
    // update: function (dt) {
 
    // },
});

通过随机生成名称,调用 cc.vv.userMgr.create(name); 进行创建操作;

Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

hall_server 负责处理创建角色的相关请求消息。

Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

通过以下方式检查玩家是否存在:db.is_user_exist(account, function(ret) {

Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

若玩家不存在,则执行创建操作:db.create_user(account, name, coins, gems, 0, null, function(ret) {

跳转到 hall 场景,并关联 Hall.js 脚本文件:.

Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio

收藏 打赏

感谢您的支持,我会继续努力的!

打开USDT(trc-20)扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

Ts:本站所有内容均为互联网收集整理和网友上传。仅限于学习研究,请必须在24小时内删除。否则由此引发的法律纠纷及连带责任本站概不承担。

如侵犯到您的合法权益,请联系我们删除侵权资源!

韩仔技术 搭建教程 Cocos Creator棋牌麻将源代码开发教程第二篇——情怀麻将的底层通讯express框架与socketio https://www.hanzijs.com/dajian/2663.html

相关文章

发表评论
暂无评论