时间有限,个别细节语法错误请无视
功能需求:
移动社交应用的服务端与客户端开发,前端需要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,需要保证请求结构体首个数据是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);
}
/******************************图片广场功能(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枚举
// 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:实测
修正增加“回传功能码”(其他所有子函数加相同处理)
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协议里