1.问题
接收到新框架下的平台服务器的810消息无法被未升级的本地服务器识别的问题.
2.分析
810-Indication消息的生成和发送:
///< 生成消息
CMsg *amsg = new CMsg;
amsg->SetMsgType(MT_INDICATION);
amsg->SetMsgID(810);
amsg->SetMsgPriority(MP_LOW);
CUMXT *tmsg = new CUMXT(amsg); ///< 用传输层封包
tmsg->SetFwdFlag(RL_NODISCARDABLE);
///< 发送
CBasePlugInModule::network_->SendMsg(tmsg);
升级到UMX4后,默认的消息版本为UMX4.
上面的代码中,amsg的协议版本为,tmsg会从amsg复制消息头的信息,版本也是4.
void CUMXT::Attach(CMsg *msg) {
app_msg_ = msg;
this->CopyHead(msg);
this->SetMsgAttr(UMXT_MASK); ///< 重新设置为传输层协议,因为CopyHead用msg的属性覆盖了
}
以下是通过连接处理器发送时转换协议为连接处理器协议版本的代码:(连接处理器的协议版本是对方能够识别的约定版本)
ACE_Message_Block*
HTX_Network::prepare_send_message(CMsg *msg,short prot_version,IProtMod *prot_mod,bool use_session_key,const char *session_key) {
...
size_t totallen;
char *data = 0;
msg->SetVersion(prot_version); ///< 设置发送的协议版本
///< 对于UMXT消息,SetVersion只设置了msg的版本,未设置内部应用消息(app_msg_)的版本.如果app_msg_已经序列化未被还原,则序列化版本可能不被接收方识别.
int ret = prot_mod->GetRawData(msg,&data,totallen,&tp);
///< prot_mod->GetRawData调用CUMXT::Stream
ACE_Message_Block *nb = 0;
ACE_NEW_RETURN(nb,ACE_Message_Block(data,totallen),0);
nb->clr_flags(ACE_Message_Block::DONT_DELETE);
nb->msg_priority(msg->GetMsgPriority()*10);
nb->wr_ptr(totallen);
return nb;
}
CUMXT::Stream的相关代码:
int CUMXT::Stream(char **buf,unsigned long &bufsize,unsigned long &datasize) {
if (app_msg_==0) { ///< 应用消息未被还原
///< 如果app_msg_未被还原,则不会进行协议转换使之符合通信要求.可能导致接收者无法识别.
...
return CMsg::Stream(buf,bufsize,datasize);
}
CUMXHelper helper;
helper.Attach(app_msg_);
if (helper.Serialize()) { ///< 序列化应用消息包
helper.Detach();
return -1;
}
...
return 0;
}
3.处理
3.1代码修改
主要代码修改逻辑如下(其它包括读取运行模式参数的代码)把HTX_Network::prepare_send_message的下列代码用后面的3行替代:
msg->SetVersion(prot_version); ///< 设置发送的协议版本
替换后:
msg->SetVersion(prot_version); ///< 设置发送的协议版本
if (HOTFOX::instance()->server_info_.run_mode_&1) { ///< 是否UMX兼容模式
msg->RecoverMsg(); ///< 对于转发的消息,本不需要解析,RecoverMsg会增加开销
msg->GetAppMsg()->SetVersion(prot_version);
}
3.2配置
hotfox.conf增加配置:<run_mode>1</run_mode> <!--运行模式 bit0-是否UMX兼容模式 默认:0 -->
4.兼容性
UMX4升级的兼容性如何保证:。新系统如gyb-e,das项目,所有程序采用UMX4
。对于原有系统,有2种情况:
(1)全面升级:升级不会出现上述情况
(2)局部替换某个程序:服务器设置协议兼容模式.