一个简单的游戏(2)

新内容

今天介绍CMessage的实现, 下面就开始:
Message.cpp
#include  " Message.h "
#include 
< string .h >

CMessage::CMessage()
{
    
this->Data = NULL;
    
this->Length = 0;
    
this->Time = 0;
    
this->Type = MT_INVALID;
}


CMessage::CMessage(
char *  msg,  int  len)
{
    
this->Type = (MESSAGE_TYPE)msg[0];      //char* msg来自Net 第一个字节标识消息类型
    
this->Length = len;
    
this->Data = new char[len];
    memcpy(
this->Data, msg, this->Length);

    time(
&this->Time);      //记录消息时间
}


CMessage::
~ CMessage()
{
    
if(this->Data != NULL)
    
{
        delete[] 
this->Data;
        
this->Data = NULL;
    }

}


消息是由专门的CMessageDispatcher集中处理的,所以存在一个消息的队列
MessageQueue.h

#ifndef MESSAGEQUEUE_H_
#define  MESSAGEQUEUE_H_

#include 
" Message.h "

class  CMessageQueue
{
public:
    CMessageQueue();
    
virtual ~CMessageQueue();

    
int AddMessage(CMessage *msg);      //将msg添加到消息队列中
    
int PopMessage(CMessage *msg);      //将队列中最老的消息POP出来, msg为输出参数

private:
    MESSAGE
* _msgHead;      //消息队列头指针, 每次就从此处POP消息
    MESSAGE
* _msgTail;         //消息队列尾, 新加入的消息就接在这儿
    
int _msgCount;                     //队列中现有的消息
    
}
;

#endif

修改

和<一个简单的游戏(1)>中的CMessage不同, 修改为如下:

#ifndef MESSAGE_H_
#define  MESSAGE_H_

#include 
< time.h >

#include 
" MessageType.h "
#include 
" NetInfo.h "

class  CMessage
{
public:
    CMessage();
    CMessage(
char* szMsg, int len);
    
virtual ~CMessage();

public:
    time_t Time;            
//create time
    MESSAGE_TYPE Type;
    
char* Data;
    
int Length;

    NET_INFO NetInfo;      //此处为新增加, 包括消息来源ip和port
}
;

struct  MESSAGE
{
    CMessage 
*msg;
    MESSAGE 
*next;
}
;

#endif

 

其中的NET_INFO定义如下:
NetInfo.h

#ifndef NETINFO_H_
#define  NETINFO_H_

struct  NET_INFO
{
    unsigned 
long ip;
    unsigned 
short port;
}
;

#endif

 

MessageType也作了修改
MessageType.h

#ifndef MESSAGETYPE_H_
#define  MESSAGETYPE_H_

enum  MESSAGE_TYPE      //具体参看后文对现有各个消息数据的描述
{
    MT_DAT 
= 0,        //c <-> s
    MT_TXT = 1,        //c <-> s
    
    MT_USR_ADD 
= 10,    //c -> s
    MT_USR_OUT = 11,    //退出    c -> s

    MT_SYS_STA 
= 20,    //系统状态询问    s <-> c
    MT_SYS_USR = 21,    //s -> c : User Info

    MT_INVALID 
= -1
}
;

#endif

 

消息格式

现在进展玩家连接服务器,玩家之间发送消息, 到此为止的消息格式如下:

char* msg[]

msg[0] : 消息类别, 最多0-127种消息,据此判断消息类别,进而进行不同的相应

msg[1-n] : 消息内容,不同消息种类不同


MT_TXT : c <-> s : 文本信息

msg[0] = MT_TXT

msg[1] = from id, -128 - 127,发送人的account id, 若为-1 则是系统信息

msg[2] = to id, -128 – 127, 当作为接收方时不等于自己的account id 则可以绝收; 否则必需指名, -1 为给所有人发消息

msg[3] = 消息有多长 0-255

msg[4-] = 消息内容

MT_USR_ADD : c <-> s : 登录

msg[0] = MT_USR_ADD

msg[1] = 名称长度 0-255

msg[2-] = 名称

MT_USR_OUT : c -> s : 退出

msg[0] = MT_USR_OUT

msg[1] = account id

MT_SYS_USR : s -> c : 其他用户信息

msg[0] = MT_SYS_USR

msg[1] = account id, 如果=-1, 说明登录失败

msg[2] = 名称长度, 0-255, 如果=0, 说明msg[1]是自己的account id

msg[3-n] = 名称

MT_SYS_STA : c <-> s : 链接状态保持

msg[0] = MT_SYS_STA

msg[1] = 服务器发送询问未得到应答的次数, 超过一定次数, 服务器将中止当前会话
所以每次收到这个消息
, 需要尽快回复不带内容的MT_SYS_STA消息(msg[0]= MT_SYS_STA)

CMessage的作用

在整个游戏中,现在对CMessage的设想是这样的:
1.客户端和服务端的所有交互, 全部使用Message. 比如登陆,注册,发言,以及今后的游戏数据(比如角色状态)
2.服务端使用一个不限长度的(目前不限)队列存放待处理的消息
3.消息有多种类型和格式
4.消息使用UDP传输, 服务端可以广播消息
5.其实Message就是本游戏通信部分的内容载体

预告

<3>说明MessageQueue.cpp, 以及简单描述一下目前状态下相关对象的关系,这个设计的逻辑结构
<4>就主要说明dispatcher如何处理
<5>开始就设计网络连接了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值