二进制mysql存储以及http发送和接收

前端:JavaScript

后端:C++ ,openresty(lua)

功能需求:后端C++游戏服务器产生的战斗战报保存为二进制格式存入mysql数据库,客户端查看战报是通过http连接nginx的web服务器拉取。

流程:

1.C++将游戏战报信息拼接成二进制数据之后,先用zlib压缩以下,进一步减小数据体积:

compress(szZipReport,  &nSize, (const unsigned char*)szReport,  nLenReport);

2.我们用的是调用存储过程的方式进行mysql数据的读写的,所以还需要将压缩过的二进制数据进行格式转换,步骤类似如下:

	//需要把每一个都格式化出来
	string hexstr;
	for( int i = 0 ; i < nSize; i++)
	{
		BYTE temp_char = *(szZipReport+i);
		char temp_str[10] = {0};
		sprintf(temp_str,"%02x",temp_char);
		hexstr += temp_str;
	}

3.格式化好之后就可以作为二进制参数传给存储过程了,注意二进制数据作为参数传递时,需要以0x开头,步骤类似如下:

std::string str("call p_fight_report_add(@a,%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, 0x%s);");
// 最后一个参数为二进制数据,传入的实际为字符串。

4.存入数据库之后,web服务器那边直接用sql语句获取得到的就是二进制格式的数据,我们web用的是lor(基于openresty的一个开源框架),自带有mysql接口,读取数据的代码大致如下:

local sql = "select log from "..config.database..config.tablename.." where id = "..reportid.." limit 1;"
local ok, err, errcode, sqlstate = mysql:query(sql)
if not ok then
	ngx.log(ngx.ERR, "select data from db  error!!!")
			return ngx.exit(500)
end

5.读取之后的数据直接用zlib解压即可,由于lor的逻辑是用lua写的,当前包并没有lua版本的zlib使用,当时就使用ffi-zlib进行了ffi转换,github地址:https://github.com/hamishforbes/lua-ffi-zlib

解压缩代码大致如下:

local strLog = ok[1].log
local input = function(bufsize)
	local d = strLog
		ngx.log(ngx.ERR, "decompress input data = "..d)
		return d
end
local output_table = {}
local output = function(data)
		table.insert(output_table, data)
end

-- Decompress the data
local ok, err = zlib.inflateGzip(input, output)
if not ok then
	ngx.log(ngx.ERR, "decompress data error!"..err)
	res:status(500):send("decompress data error!")
	return
end

local realRes = table.concat(output_table,'')

-- realRes为解压出来的二进制数据
res:send(realRes, 'application/gif')

6.客户端JavaScript这边用的是cocos creator引擎,获取并解析为arraybuffer的代码如下:

	requestReport(url, succ, fail) {
		let xhr = cc.loader.getXMLHttpRequest()    
		let self = this
		xhr.onreadystatechange = function () {
			if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status < 400)) {
				// let response = xhr.responseText;
				let response = xhr.response;
				let reader = new FileReader();
				// response为blob对象
				reader.readAsArrayBuffer(response);
				reader.onload = (e) => {
					if (succ) {
						succ(reader.result)    // reader.result 为arrayBuffer
					}
				}
			} else if (fail) {
				fail()
			}
		};
		xhr.open('GET', url, true);
		xhr.responseType = 'blob';
		xhr.send();
	},

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值