服务器自定义协议优化——“请求JSON功能”子协议的分离

时间有限,个别细节语法错误请无视


功能需求:

移动社交应用的服务端与客户端开发,前端需要JSON形式返回服务器查询结果,一般JSON直接在数据库查询时候用SQL函数拼好了,这样做:

一是比较省空间,JSON比XML之类的小(虽然比数据结构大);

二是便于修改,只需要在json后边加key-value就能适应不(bu)断(neng)变(ming)化(que)的需求,而不用去更改结构体,更改程序逻辑。

综合来讲JSON是最佳方案。

本程序的通信协议使用两位十六进制(一个字节),协议资源有限,而返回JSON的功能越来越多,过多的重复功能浪费了协议空间~所以我想到了优化协议。



如下为客户端的协议接收处理逻辑:

		// 接收到朋友圈列表信息
		case IM_FUN_CIRCLE_RE_LIST:
		// 接收到热点区域信息
		case IM_FUN_RE_HOT:
		// 排行
		case IM_FUN_RE_RANKING:
		// 手机号校验状态
		case IM_FUN_RE_CONTACT_ADD:
		// 对我放置的雷信息
		case IM_FUN_RE_MY_FRIEND_MINES:
		// 雷的明细
		case IM_FUN_MINES_RECORD:
		case IM_FUN_AREA_MINES:
		case IM_FUN_GET_IMG_LIST:
		case IM_FUN_GET_ALBUM_LIST:
		//获取心情列表
		case FUN_GET_FEELING_LIST:
		//获取热点地区(学校):
		case FUN_GET_HOT_AREA_LIST:
		//获取用户全面详细信息
//		case IM_FUN_USER_OVERALL_INFO:
		//获取开通ING学校列表
		case FUN_GET_SCHOOL_LIST_WITH_ING:
		//获取学校内ING分页列表
		case FUN_GET_ING_CONTENT_LIST:
		//获取ING评论的分页列表
		case FUN_GET_ING_COMMENT_LIST:
			RecvJson(iFun, pcRecv, iLen);
			break;

可以看到,多个协议走了一个RecvJson回调,这有一半是前任留下的弊病,有一半是自己模仿追加的累赘。

随着产品的迭代,类似功能越来越多,觉得是该统一接收JSON的协议,节省协议空间了。



按完整的从请求到最后完成的顺序来

客户端发送请求过程:

int c_GetINGListNotice(long long _llPageStartIndex)
{
	int iCount = im_pub_GetDataStart();
	char pcSend[10240];
	
	TOneJsonData *ptOneJsonData = (TOneJsonData *)(pcSend + iCount);
	if(NULL == ptOneJsonData)
	{
		dbg();
		return ERR;
	}

	ptOneJsonData->m_llPageStartIndex = _llPageStartIndex;
	ptOneJsonData->m_iJsonType= JSON_TYPE_LIST_ING_NOTICE;

	iCount += sizeof(TOneJsonData);
	im_pub_SetFrameHead(pcSend, iCount - im_pub_GetHeadLen(), FUN_GET_JSON, g_SendSerial++);
	im_pub_SetFrameEnd(pcSend, iCount);

	iCount += im_pub_GetEndLen();

	return SendData(pcSend,iCount);	

}


这是比较无解的一个难点,发送要绑定数据结构,每个请求不同, 传入的参数也就不尽相同,数据结构也就不同,此例只是暂时使用了服务端返回时用的数据结构,但是放到其他情况肯定是不够用的:

//发送一个JSON字符串
typedef struct
{
	int m_iJsonType;
	long long m_llPageStartIndex;
	TOneStringData m_tOneStringData;
}TOneJsonData;

唯一想到的是使用暴力方法,既然数据结构都要变,那我可以不管。
任你结构体如何变,只要保证第一个参数是JsonType, 服务端接收时强行提取就完了。


服务器接收逻辑:

解包过程忽略,这是解出来的真正协议功能号FUN_GET_JSON:


		case FUN_GET_JSON:
			iRet = s_AnalyGetJson(_ptService, _ptEcIm, _pcData, _iLen);
			im_s_ReplyReturn(_ptEcIm, _iFun, iRet);
			break;

头文件定义

包裹函数加子函数

/********************************获取JSON通用功能***********************************/
//JSON通用处理接口
int s_AnalyGetJson(TDbService *_ptService, TEcIm *_ptEcIm, char *_pcData, int _iLen);
//JSON子处理逻辑
int json_AnalyListINGNotice(TDbService *_ptService, TEcIm *_ptEcIm, char *_pcData, int _iLen);
int json_AnalyListINGMyPublish(TDbService *_ptService, TEcIm *_ptEcIm, char *_pcData, int _iLen);
int json_AnalyListINGMyParticipate(TDbService *_ptService, TEcIm *_ptEcIm, char *_pcData, int _iLen);



/*****************************************************************************************/





服务端开始处理获取JSON请求,将JsonType强行提取,进行提取,然后分各功能逻辑处理:


int s_AnalyGetJson(TDbService *_ptService, TEcIm *_ptEcIm, char *_pcData, int _iLen)
	
{
	int iCount = im_pub_GetDataStart();
	//强行取出JSONTYPE,需要保证请求结构体首个数据是JSONTYPE
	int *piJsonType = (int *)(_pcData + iCount);
	dbgx(*piJsonType);
	int iRet = 0;
	switch(*piJsonType)
	{
		case JSON_TYPE_LIST_ING_NOTICE:
		{
			iRet = json_AnalyListINGNotice(_ptService,_ptEcIm, _pcData, _iLen);
			break;
		}
		case JSON_TYPE_LIST_ING_MY_PUBLISH:
		{
			iRet = json_AnalyListINGMyPublish(_ptService,_ptEcIm, _pcData, _iLen);
			break;
		}
		case JSON_TYPE_LIST_ING_MY_PARTICIPATE:
		{
			iRet = json_AnalyListINGMyParticipate(_ptService,_ptEcIm, _pcData, _iLen);
			break;
		}
		default:
			iRet = 0;
			break;
	}
	return iRet;
}

服务端JSON子处理函数:

此例请求和回复用了同一种结构体(见服务器返回结构体设计),其他请求可能结构体就不同了,但是首数据都保证是int型的JsonType枚举值。

int json_AnalyListINGNotice(TDbService *_ptService, TEcIm *_ptEcIm, char *_pcData, int _iLen)
{
	long long llUserId = im_s_GetUserId(_ptEcIm);	
	if(llUserId <= 0)
	{
		dbg();
		return ERR;
	}

	int iCount = im_pub_GetDataStart();
	TOneJsonData *ptOneRecvJsonData = (TOneJsonData *)(_pcData + iCount);
	if(NULL == ptOneRecvJsonData)
	{
		dbg();
		return ERR;
	}

	char pcSend[256000];
	TOneJsonData *ptOneSendJsonData = (TOneJsonData *)(pcSend + iCount); 

	if(NULL == ptOneSendJsonData)
	{
		dbg();
		return ERR;
	}

	iCount += sizeof(TOneJsonData);//变长字符串,怎么确定长度
	
	ptOneSendJsonData->m_tOneStringData->m_iLen = db_ReplyINGNoticeList(_ptService, llUserId, 
												ptOneRecvJsonData->m_llPageStartIndex, 
												ptOneSendJsonData->m_tOneStringData->m_pcData, sizeof(pcSend) - iCount - im_pub_GetEndLen());//输出

	iCount += ptOneSendJsonData->m_tOneStringData->m_iLen;

	// 合成帧头帧尾
	im_pub_SetFrameHead(pcSend, iCount - im_pub_GetHeadLen(), FUN_GET_JSON, _ptEcIm->m_cSendSerial++);
	im_pub_SetFrameEnd(pcSend, iCount);

	iCount += im_pub_GetEndLen();
	
	return SendData(_ptEcIm, pcSend, iCount);

}

其余两个雷同

数据库接口:

int db_ReplyINGNoticeList(TDbService* _ptService, long long _llUser,
							long long _llPageStartCommentId,
							char *_pcOut, int _iMaxLen)
{
	char pcSql[256000];

	snprintf(pcSql, sizeof(pcSql), "SELECT f_list_ing_notice(%lld,%lld) AS m_ret", _llUser, _llPageStartCommentId);
	
	return db_mysql_DoSqlOneString(_ptService, pcSql, _pcOut, _iMaxLen);

}
int db_ReplyINGMyPublishList(TDbService* _ptService, long long _llUser,
							long long _llPageStartCommentId,
							char *_pcOut, int _iMaxLen)
{
	char pcSql[256000];

	snprintf(pcSql, sizeof(pcSql), "SELECT f_list_ing_my_publish(%lld,%lld) AS m_ret", _llUser, _llPageStartCommentId);
	
	return db_mysql_DoSqlOneString(_ptService, pcSql, _pcOut, _iMaxLen);

}

int db_ReplyINGMyParticipateList(TDbService* _ptService, long long _llUser,
							long long _llPageStartCommentId,
							char *_pcOut, int _iMaxLen)
{
	char pcSql[256000];

	snprintf(pcSql, sizeof(pcSql), "SELECT f_list_ing_my_participate(%lld,%lld) AS m_ret", _llUser,  _llPageStartCommentId);
	
	return db_mysql_DoSqlOneString(_ptService, pcSql, _pcOut, _iMaxLen);

}





JSON子处理逻辑的数据操作就和其他功能放在一起了,无差别。


/******************************图片广场功能(ING)***********************************/
//返回开通ING的学校列表,合成JSON,_llUser有用,用以查明自己的身份(归属学校Id)
int db_GetSchoolListWithING(TDbService* _ptService, long long _llUser, char *_pcOut, int _iMaxLen);
//发布ING
int db_UpdateING(TDbService* _ptService, long long _llUser, char *_pcPicUrl, char* _pcTags,
							char *_pcDescription, int _iSchoolId, int _iOpenEnable, int _iMinutes);
//获取ING列表,合成JSON,按学校、分页
int db_GetINGContentList(TDbService* _ptService, long long _llUser, int _iSchoolId, 
							int _iOpenEnable, long long _llPageStartContentId,
							char *_pcOut, int _iMaxLen);
//赞ING内容
int db_UpdateINGLike(TDbService* _ptService, long long _llSrcUserId, int _iContentId);
//评论ING内容
int db_UpdateINGComment(TDbService* _ptService, long long _llSrcUser, long long _llContentdId, 
						long long _llDstUserId, char* _pcComment);

//分页获取ING评论列表,合成JSON
int db_GetINGCommentList(TDbService* _ptService, long long _llUser, long long _llContentId, 
							long long _llPageStartCommentId,
							char *_pcOut, int _iMaxLen);

//JSON子接口对应的ING处理函数
//ING通知列表
int db_ReplyINGNoticeList(TDbService* _ptService, long long _llUser,
							long long _llPageStartCommentId,
							char *_pcOut, int _iMaxLen);
//我发布的ING列表
int db_ReplyINGMyPublishList(TDbService* _ptService, long long _llUser, 
							long long _llPageStartCommentId,
							char *_pcOut, int _iMaxLen);
//我参与的ING列表
int db_ReplyINGMyParticipateList(TDbService* _ptService, long long _llUser,
							long long _llPageStartCommentId,
							char *_pcOut, int _iMaxLen);


/*****************************************************************************************/


到数据库接口这一层,就和其他功能一致了。只不过是外层解包和封包逻辑略有不同,然后查询结果的存储介质由TOneStringData变成了TOndJsonData,下面需要的就是客户端的解包处理。


服务器接收数据测试:


[2015/03/14 11:44:49 29567 3050494832]src/im_server.c,ImAnaly,898 ptEcIm->m_cCurrentSerial = 1
[2015/03/14 11:44:49 29567 3050494832]src/im_server.c,ImAnaly,899 cGetSendSerial = 1
[2015/03/14 11:44:49 29567 3050494832]src/im_server.c,AnalyShort,55 <span style="color:#ff0000;">_iFun = 0xf1</span>
[2015/03/14 11:44:49 29567 3050494832]src/hash_service.c,hash_socket_Lookup,266 _iSocket = 16
[2015/03/14 11:44:49 29567 3050494832]src/im_server.c,AnalyShort,70 _iFun = -5575002480900570895
[2015/03/14 11:44:49 29567 3050494832]src/hash_service.c,hash_socket_Lookup,266 _iSocket = 16
[2015/03/14 11:44:49 29567 3050494832]src/im_server_service.c,s_AnalyGetJson,6073 <span style="color:#ff0000;">*piJsonType = 0x1</span>
[2015/03/14 11:44:49 29567 3050494832]src/network.c,net_Send,549 _iLen = 17
[2015/03/14 11:44:49 29567 3050494832]src/im_server.c,ImAnaly,898 ptEcIm->m_cCurrentSerial = 2
[2015/03/14 11:44:49 29567 3050494832]src/im_server.c,ImAnaly,899 cGetSendSerial = 2
[2015/03/14 11:44:49 29567 3050494832]src/im_server.c,AnalyShort,55 <span style="color:#ff0000;">_iFun = 0xf1</span>
[2015/03/14 11:44:49 29567 3050494832]src/hash_service.c,hash_socket_Lookup,266 _iSocket = 16
[2015/03/14 11:44:49 29567 3050494832]src/im_server.c,AnalyShort,70 _iFun = -5575001862425280271
[2015/03/14 11:44:49 29567 3050494832]src/hash_service.c,hash_socket_Lookup,266 _iSocket = 16
[2015/03/14 11:44:49 29567 3050494832]src/im_server_service.c,s_AnalyGetJson,6073 <span style="color:#ff0000;">*piJsonType = 0x2</span>
[2015/03/14 11:44:49 29567 3050494832]src/network.c,net_Send,549 _iLen = 17
[2015/03/14 11:44:49 29567 3050494832]src/im_server.c,ImAnaly,898 ptEcIm->m_cCurrentSerial = 3
[2015/03/14 11:44:49 29567 3050494832]src/im_server.c,ImAnaly,899 cGetSendSerial = 3
[2015/03/14 11:44:49 29567 3050494832]src/im_server.c,AnalyShort,55 <span style="color:#ff0000;">_iFun = 0xf1</span>
[2015/03/14 11:44:49 29567 3050494832]src/hash_service.c,hash_socket_Lookup,266 _iSocket = 16
[2015/03/14 11:44:49 29567 3050494832]src/im_server.c,AnalyShort,70 _iFun = -5575001862425280271
[2015/03/14 11:44:49 29567 3050494832]src/hash_service.c,hash_socket_Lookup,266 _iSocket = 16
[2015/03/14 11:44:49 29567 3050494832]src/im_server_service.c,s_AnalyGetJson,6073<span style="color:#ff0000;"> *piJsonType = 0x3</span>

测试成功,功能号和JsonType都接收成功






服务器返回给客户端的结构体设计:

// 发送一个String
typedef struct
{
	int m_iLen;
	char m_pcData[0];
}TOneStringData;
//发送一个JSON字符串
typedef struct
{
	int m_iJsonType;
	long long m_llPageStartIndex;
	TOneStringData m_tOneStringData;
}TOneJsonData;

之前的返回结构体是TOneStringData,现在把它拼到新的TOneJsonData结构体下,以后返回Json结构体。



返回结构体打包与发送

见JSON处理子逻辑




客户端接收服务器数据

拆出JsonType传给RecvJson

现在就不该叫_iFun了,iJsonType更恰当点。

前边会解析出真正的功能码,我新加的FUN_GET_JSON
case 以后解包出jsontype,传递给recvJson当第一个参数。


新的拆包与回调映射逻辑——可以和文章头部的老逻辑对比:


		// 接收到朋友圈列表信息
		case IM_FUN_CIRCLE_RE_LIST:
		// 接收到热点区域信息
		case IM_FUN_RE_HOT:
		// 排行
		case IM_FUN_RE_RANKING:
		// 手机号校验状态
		case IM_FUN_RE_CONTACT_ADD:
		// 对我放置的雷信息
		case IM_FUN_RE_MY_FRIEND_MINES:
		// 雷的明细
		case IM_FUN_MINES_RECORD:
		case IM_FUN_AREA_MINES:
		case IM_FUN_GET_IMG_LIST:
		case IM_FUN_GET_ALBUM_LIST:
		//获取心情列表
		case FUN_GET_FEELING_LIST:
		//获取热点地区(学校):
		case FUN_GET_HOT_AREA_LIST:
		//获取用户全面详细信息
//		case IM_FUN_USER_OVERALL_INFO:
		//获取开通ING学校列表
		case FUN_GET_SCHOOL_LIST_WITH_ING:
		//获取学校内ING分页列表
		case FUN_GET_ING_CONTENT_LIST:
		//获取ING评论的分页列表
		case FUN_GET_ING_COMMENT_LIST:
			RecvJson(iFun, pcRecv, iLen);
			break;
		//合并JSON回调,用JsonType代替iFun
		case FUN_GET_JSON:
			int iCount = im_pub_GetDataStart();
			int *piJsonType = (int *)(pcRecv + iCount);//从接受数据库拆出JsonTyp
			int iJsonType = *piJsonType;
			dbgx(iJsonType);
			RecvJson(iJsonType, pcRecv, iLen);
			break;

更正(其实还不对):

		// 接收到朋友圈列表信息
		case IM_FUN_CIRCLE_RE_LIST:
		// 接收到热点区域信息
		case IM_FUN_RE_HOT:
		// 排行
		case IM_FUN_RE_RANKING:
		// 手机号校验状态
		case IM_FUN_RE_CONTACT_ADD:
		// 对我放置的雷信息
		case IM_FUN_RE_MY_FRIEND_MINES:
		// 雷的明细
		case IM_FUN_MINES_RECORD:
		case IM_FUN_AREA_MINES:
		case IM_FUN_GET_IMG_LIST:
		case IM_FUN_GET_ALBUM_LIST:
		//获取心情列表
		case FUN_GET_FEELING_LIST:
		//获取热点地区(学校):
		case FUN_GET_HOT_AREA_LIST:
		//获取用户全面详细信息
//		case IM_FUN_USER_OVERALL_INFO:
		//获取开通ING学校列表
		case FUN_GET_SCHOOL_LIST_WITH_ING:
		//获取学校内ING分页列表
		case FUN_GET_ING_CONTENT_LIST:
		//获取ING评论的分页列表
		case FUN_GET_ING_COMMENT_LIST:
			RecvJson(iFun, pcRecv, iLen);
			break;
		//合并JSON回调,用JsonType代替iFun
		case FUN_GET_JSON:
			int iCount = im_pub_GetDataStart();

			TOneJsonData * ptOneJsonData = (TOneJsonData *)(pcRecv + iCount);
			int iJsonType = ptOneJsonData->m_iJsonType;
			dbgx(iJsonType);
			RecvJson(iJsonType, ptOneJsonData->m_tOneStringData, iLen);
			break;

更正2:

问题点:


static int RecvJson(int _iFun, char *_pcData, int _iLen)
{

	TOneStringData *ptOneData = (TOneStringData *)(_pcData + im_pub_GetDataStart());

	return CallBackJson(_iFun, ptOneData.m_pcData, ptOneData.m_iLen);
}


因为recvJson本身有解包,带协议头,并且解包只针对TOneStringData,而不能兼容TOneJsonData,所以不能擅自偏移,原封不动传也不对,所以要改recvJson



将解包拿到外面去做

// 接收到朋友圈列表
static int RecvJson(int _iFun, char *_pcData, int _iLen)
{
	return CallBackJson(_iFun, _pcData, _iLen);
}

外部操作:


		// 接收到朋友圈列表信息
		case IM_FUN_CIRCLE_RE_LIST:
		// 接收到热点区域信息
		case IM_FUN_RE_HOT:
		// 排行
		case IM_FUN_RE_RANKING:
		// 手机号校验状态
		case IM_FUN_RE_CONTACT_ADD:
		// 对我放置的雷信息
		case IM_FUN_RE_MY_FRIEND_MINES:
		// 雷的明细
		case IM_FUN_MINES_RECORD:
		case IM_FUN_AREA_MINES:
		case IM_FUN_GET_IMG_LIST:
		case IM_FUN_GET_ALBUM_LIST:
		//获取心情列表
		case FUN_GET_FEELING_LIST:
		//获取热点地区(学校):
		case FUN_GET_HOT_AREA_LIST:
		//获取用户全面详细信息
//		case IM_FUN_USER_OVERALL_INFO:
		//获取开通ING学校列表
		case FUN_GET_SCHOOL_LIST_WITH_ING:
		//获取学校内ING分页列表
		case FUN_GET_ING_CONTENT_LIST:
		//获取ING评论的分页列表
		case FUN_GET_ING_COMMENT_LIST:
			TOneStringData *ptOneData = (TOneStringData *)(pcRecv + im_pub_GetDataStart());
			RecvJson(iFun, ptOneData->m_pcData, ptOneData->m_iLen);
			break;
		//合并JSON回调,用JsonType代替iFun
		case FUN_GET_JSON:
			TOneJsonData * ptOneJsonData = (TOneJsonData *)(pcRecv +  im_pub_GetDataStart());
			int iJsonType = ptOneJsonData->m_iJsonType;
			dbgx(iJsonType);
			RecvJson(iJsonType, ptOneJsonData->m_tOneStringData.m_pcData, ptOneJsonData->m_tOneStringData.m_iLen);
			break;


之前以为RecvJson是回调,其实还有一层,CallBackRecv才是回调,不过把解包这些操作扒掉以后,这一层封装意义也不大了,也可以直接裸奔,CallBack


		// 接收到朋友圈列表信息
		case IM_FUN_CIRCLE_RE_LIST:
		// 接收到热点区域信息
		case IM_FUN_RE_HOT:
		// 排行
		case IM_FUN_RE_RANKING:
		// 手机号校验状态
		case IM_FUN_RE_CONTACT_ADD:
		// 对我放置的雷信息
		case IM_FUN_RE_MY_FRIEND_MINES:
		// 雷的明细
		case IM_FUN_MINES_RECORD:
		case IM_FUN_AREA_MINES:
		case IM_FUN_GET_IMG_LIST:
		case IM_FUN_GET_ALBUM_LIST:
		//获取心情列表
		case FUN_GET_FEELING_LIST:
		//获取热点地区(学校):
		case FUN_GET_HOT_AREA_LIST:
		//获取用户全面详细信息
//		case IM_FUN_USER_OVERALL_INFO:
		//获取开通ING学校列表
		case FUN_GET_SCHOOL_LIST_WITH_ING:
		//获取学校内ING分页列表
		case FUN_GET_ING_CONTENT_LIST:
		//获取ING评论的分页列表
		case FUN_GET_ING_COMMENT_LIST:
			TOneStringData *ptOneData = (TOneStringData *)(pcRecv + im_pub_GetDataStart());
			CallBackJson(iFun, ptOneData->m_pcData, ptOneData->m_iLen);
			break;
		//合并JSON回调,用JsonType代替iFun
		case FUN_GET_JSON:
			TOneJsonData * ptOneJsonData = (TOneJsonData *)(pcRecv +  im_pub_GetDataStart());
			int iJsonType = ptOneJsonData->m_iJsonType;
			dbgx(iJsonType);
			CallBackJson(iJsonType, ptOneJsonData->m_tOneStringData.m_pcData, ptOneJsonData->m_tOneStringData.m_iLen);
			break;

更正3:语法错误,外部指针用“->”,内部实体用"." SWITCH CASE内不能声明变量,除非加括号



		// 接收到朋友圈列表信息
		case IM_FUN_CIRCLE_RE_LIST:
		// 接收到热点区域信息
		case IM_FUN_RE_HOT:
		// 排行
		case IM_FUN_RE_RANKING:
		// 手机号校验状态
		case IM_FUN_RE_CONTACT_ADD:
		// 对我放置的雷信息
		case IM_FUN_RE_MY_FRIEND_MINES:
		// 雷的明细
		case IM_FUN_MINES_RECORD:
		case IM_FUN_AREA_MINES:
		case IM_FUN_GET_IMG_LIST:
		case IM_FUN_GET_ALBUM_LIST:
		//获取心情列表
		case FUN_GET_FEELING_LIST:
		//获取热点地区(学校):
		case FUN_GET_HOT_AREA_LIST:
		//获取用户全面详细信息
//		case IM_FUN_USER_OVERALL_INFO:
		//获取开通ING学校列表
		case FUN_GET_SCHOOL_LIST_WITH_ING:
		//获取学校内ING分页列表
		case FUN_GET_ING_CONTENT_LIST:
		//获取ING评论的分页列表
		case FUN_GET_ING_COMMENT_LIST:
		{
			TOneStringData *ptOneData = (TOneStringData *)(pcRecv + im_pub_GetDataStart());
			CallBackJson(iFun, ptOneData.m_pcData, ptOneData.m_iLen);
			break;
		}
		//合并JSON回调,用JsonType代替iFun
		case FUN_GET_JSON:
		{
			TOneJsonData * ptOneJsonData = (TOneJsonData *)(pcRecv +  im_pub_GetDataStart());
			int iJsonType = ptOneJsonData->m_iJsonType;
			dbgx(iJsonType);
			CallBackJson(iJsonType, ptOneJsonData->m_tOneStringData.m_pcData, ptOneJsonData->m_tOneStringData.m_iLen);
			break;
		}




剩下的,就是IOS与安卓前端根据枚举值不同,映射到不同功能了

JSON枚举

通过沟通协调,IOS和安卓的前端没有问题,只要那个所谓“_iFun”的数字一致即可,以前有的数字还照搬,新的就新加(稍后会写上完整的)。


// JSON请求类型
enum
{
	JSON_TYPE_LIST_ING_NOTICE			= 0x01,	//获取ING通知列表
	JSON_TYPE_LIST_ING_MY_PUBLISH		= 0x02, //获取我发起的ING列表
	JSON_TYPE_LIST_ING_MY_PARTICIPATE	= 0x03, //获取我参与的ING列表

	//老枚举的兼容
	JSON_TYPE_LIST_CIRCLE				= 0xA3, // 接收到朋友圈列表信息,原IM_FUN_CIRCLE_RE_LIST
	JSON_TYPE_LIST_HOT					= 0x16, // 接收到热点区域信息IM_FUN_RE_HOT
	JSON_TYPE_LIST_RANKING				= 0x18, // 排行IM_FUN_RE_RANKING
	JSON_TYPE_LIST_CONTACT_ADD			= 0x56, // 手机号校验状态IM_FUN_RE_CONTACT_ADD
	JSON_TYPE_LIST_MY_FRIEND_MINES		= 0x9A, // 对我放置的雷信息IM_FUN_RE_MY_FRIEND_MINES
	JSON_TYPE_LIST_MINES_RECORD			= 0x9D, // 雷的明细IM_FUN_MINES_RECORD
	JSON_TYPE_LIST_AREA_MINES			= 0x14, //IM_FUN_AREA_MINES
	JSON_TYPE_LIST_IMG					= 0xA9, //IM_FUN_GET_IMG_LIST
	JSON_TYPE_LIST_ALBUM				= 0xAA, //IM_FUN_GET_ALBUM_LIST
	JSON_TYPE_LIST_FEELING				= 0x4b, //获取心情列表FUN_GET_FEELING_LIST:
	JSON_TYPE_LIST_HOT_AREA				= 0x4c, //获取热点地区(学校)FUN_GET_HOT_AREA_LIST:
	JSON_TYPE_LIST_SCHOOL_WITH_ING		= 0xd4,	//获取开通ING学校列表FUN_GET_SCHOOL_LIST_WITH_ING:	
	JSON_TYPE_LIST_ING_CONTENT			= 0xd6, //获取学校内ING分页列表FUN_GET_ING_CONTENT_LIST:
	JSON_TYPE_LIST_ING_REPLY			= 0xd9, //获取ING评论的分页列表FUN_GET_ING_COMMENT_LIST:
				//获取用户全面详细信息
				//case IM_FUN_USER_OVERALL_INFO:
}TImJsonType;


更正4:实测

有点小错误,发送请求和调用时没问题了,就是回传的时候功能码没给到位,_iFun都是0


服务器自定义协议优化——“请求JSON功能”子协议的分离_第1张图片

修正增加“回传功能码”(其他所有子函数加相同处理)

int json_AnalyListINGNotice(TDbService *_ptService, TEcIm *_ptEcIm, char *_pcData, int _iLen)
{
	long long llUserId = im_s_GetUserId(_ptEcIm);	
	if(llUserId <= 0)
	{
		dbg();
		return ERR;
	}

	int iCount = im_pub_GetDataStart();
	TOneJsonData *ptOneRecvJsonData = (TOneJsonData *)(_pcData + iCount);
	if(NULL == ptOneRecvJsonData)
	{
		dbg();
		return ERR;
	}

	char pcSend[256000];
	TOneJsonData *ptOneSendJsonData = (TOneJsonData *)(pcSend + iCount); 

	if(NULL == ptOneSendJsonData)
	{
		dbg();
		return ERR;
	}

ptOneSendJsonData->m_iJsonType = ptOneRecvJsonData->m_iJsonType;//回传功能码
	iCount += sizeof(TOneJsonData);
	
	ptOneSendJsonData->m_tOneStringData.m_iLen = db_ReplyINGNoticeList(_ptService, llUserId, 
												ptOneRecvJsonData->m_llPageStartIndex, 
												ptOneSendJsonData->m_tOneStringData.m_pcData, sizeof(pcSend) - iCount - im_pub_GetEndLen());//输出

	iCount += ptOneSendJsonData->m_tOneStringData.m_iLen;

	// 合成帧头帧尾
	im_pub_SetFrameHead(pcSend, iCount - im_pub_GetHeadLen(), FUN_GET_JSON, _ptEcIm->m_cSendSerial++);
	im_pub_SetFrameEnd(pcSend, iCount);

	iCount += im_pub_GetEndLen();
	
	return SendData(_ptEcIm, pcSend, iCount);

}

服务器自定义协议优化——“请求JSON功能”子协议的分离_第2张图片




完成:功能和以前一致,改动对前端是透明的


后续优化

把以前的获取JSON格式列表的请求封装到GET_JSON协议下

返回也封装到JSON协议里





你可能感兴趣的:(服务器自定义协议优化——“请求JSON功能”子协议的分离)