服务器自定义协议优化——“请求JSON功能”子协议的分离
来源:互联网 发布:淘宝卖家修改快递单号 编辑:程序博客网 时间:2024/06/04 17:50
时间有限,个别细节语法错误请无视
功能需求:
移动社交应用的服务端与客户端开发,前端需要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;
唯一想到的是使用暴力方法,既然数据结构都要变,那我可以不管。
服务器接收逻辑:
解包过程忽略,这是解出来的真正协议功能号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,需要保证请求结构体首个数据是JSONTYPEint *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);}
/******************************图片广场功能(ING)***********************************///返回开通ING的学校列表,合成JSON,_llUser有用,用以查明自己的身份(归属学校Id)int db_GetSchoolListWithING(TDbService* _ptService, long long _llUser, char *_pcOut, int _iMaxLen);//发布INGint 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评论列表,合成JSONint 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都接收成功
服务器返回给客户端的结构体设计:
// 发送一个Stringtypedef 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代替iFuncase FUN_GET_JSON:int iCount = im_pub_GetDataStart();int *piJsonType = (int *)(pcRecv + iCount);//从接受数据库拆出JsonTypint 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代替iFuncase 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代替iFuncase 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代替iFuncase 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代替iFuncase 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枚举
// 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_LISTJSON_TYPE_LIST_HOT= 0x16, // 接收到热点区域信息IM_FUN_RE_HOTJSON_TYPE_LIST_RANKING= 0x18, // 排行IM_FUN_RE_RANKINGJSON_TYPE_LIST_CONTACT_ADD= 0x56, // 手机号校验状态IM_FUN_RE_CONTACT_ADDJSON_TYPE_LIST_MY_FRIEND_MINES= 0x9A, // 对我放置的雷信息IM_FUN_RE_MY_FRIEND_MINESJSON_TYPE_LIST_MINES_RECORD= 0x9D, // 雷的明细IM_FUN_MINES_RECORDJSON_TYPE_LIST_AREA_MINES= 0x14, //IM_FUN_AREA_MINESJSON_TYPE_LIST_IMG= 0xA9, //IM_FUN_GET_IMG_LISTJSON_TYPE_LIST_ALBUM= 0xAA, //IM_FUN_GET_ALBUM_LISTJSON_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:实测
修正增加“回传功能码”(其他所有子函数加相同处理)
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格式列表的请求封装到GET_JSON协议下
返回也封装到JSON协议里
- 服务器自定义协议优化——“请求JSON功能”子协议的分离
- 服务器接口json格式的数据协议
- mina仿qq聊天功能,自定义协议,协议的编码和解码详解,发送xml对象json,mina开发大全,详细api,mina心跳
- 可以传中文参数的自定义http协议请求方式
- ym——Android从零开始(16)(HTTP协议请求、获取图片、json数据)(新)
- HTTP协议post请求返回json数据
- swoole入门教程05-Swoole的自定义协议功能的使用
- HTTP协议请求和响应格式——基于文本行的协议
- HTTP协议—— 简单认识网络请求过程中使用的协议
- Java_基础—网络编程(TCP协议代码及其优化和服务器多线程优化)
- 文件传输协议的服务器
- soap协议转换成wsdl请求服务器
- HTTP协议——网络请求
- Json协议
- HTTP的请求协议概述
- http协议的post请求
- Http协议请求的解析
- HTTP协议的请求方法
- 使用WIFI或网线连接Android设备进行调试
- mysql中的排序问题
- hdu 1754 I Hate It (单点更新,区间最值)
- Lq_Fibonacci
- ubuntu14.10下追加磁盘空间
- 服务器自定义协议优化——“请求JSON功能”子协议的分离
- 鼠标点击弹出层区域外关闭层
- Android中一些系统常量的值
- 构造函数的运用之小陷阱
- const 指针与指向const的指针
- Web 前端开发修炼之道总结
- 对类的复制构造函数的思考
- 单片机与嵌入式,你选择学什么
- Java的命名规范