myicq1.0a1服务器代码分析(三)服务器集群

    技术2022-05-11  134

    myicq1.0a1服务器代码分析()服务器集群

    顾剑辉(Solarsoft)

    服务器集群其实是服务器之间建立联系,并维护这样的联系,:玩联众时,你会看到很多服务器,那它们是怎样共同工作的呢!分析如下:

    服务器与服务器之间一般用TCP进行连接,并在每个服务器中都建立这个表,表中包括相应的信息,如服务器IP,port,包括游戏的每个服务器在线人员人数,等等.当你进入别的游戏主机时,其实是一个退出当前服务器,登入其他服务器的过程,相应的在线数据,服务器之间会传送好的.

    接下去,我们一起来看一下,myicq是怎样做到集群的.

    class ServerHash {

    public:

           void put(Server *s) {

                  int i = hashfn(s->ip);

                  hash[i].addHead(&s->hashItem);

           }

           Server *get(uint32 ip);

     

    private:

           int hashfn(uint32 ip) {

                  return (ip & (SERVER_HASH_SIZE - 1));

           }

     

           ListHead hash[SERVER_HASH_SIZE];

    };

     

    Server *ServerHash::get(uint32 ip)

    {

           int i = hashfn(ip);

           ListHead *head = &hash[i];

           ListHead *pos;

     

           LIST_FOR_EACH(pos, head) {

                  Server *s = LIST_ENTRY(pos, Server, hashItem);

                  if (s->ip == ip)

                         return s;

           }

           return NULL;

    }

    ListHead Server::serverList;

    static ServerHash serverHash;

    这里其实是服务器在线列表的hash表管理,这个hash管理不清楚的,你可以看一下我的文章().

    再来看一下,用于服务器连接的socket,其中RefObject是起个计数器的作用.

    class Server : public RefObject {

    public:

           Server();

           virtual ~Server();

     

           void onDnsResolved(uint32 ip);

           void onConnect();

           void onReceive();

           void onClose();

     

           bool connect(uint32 ip, uint16 port);

           RemoteSession *getSession(uint32 uin);

     

           void sendUserOnline(Session *s);

           void sendUserOffline(uint32 uin);

           void sendUserStatus(uint32 uin, uint32 status);

           void sendMessage(uint8 type, uint32 dst, uint32 src, ICQ_STR &text);

           void addFriend(uint16 seq, uint32 dst, uint32 src);

           void delFriend(uint32 dst, uint32 src);

           void updateContact(uint16 seq, uint32 dst, uint32 src);

           void searchRandom(uint16 seq, uint32 src);

           void searchUIN(uint16 seq, uint32 dst, uint32 src);

     

           void addFriendReply(uint16 seq, uint32 dst, uint32 src, uint8 auth);

           void updateContactReply(uint16 seq, uint32 src, uint8 *data, int n);

           void searchUINReply(uint16 seq, uint32 src, uint8 *data, int n);

     

           static bool init();

           static void destroy();

           static Server *getServer(const char *name);

           static Server *createServer(const char *name);

           static RemoteSession *getSession(QID &qid);

           static int generateFds(fd_set &readfds, fd_set &writefds);

           static void examineFds(fd_set &readfds, fd_set &writefds);

     

           static ListHead serverList;

     

           char domainName[MAX_DOMAIN_NAME + 1];

           char descName[MAX_DESC_NAME + 1];

           ICQ_STR domain;

           ICQ_STR desc;

     

           uint32 ip;

           int sock;

           int status;

           time_t expire;

           uint32 sessionCount;

           bool isAccepted;

     

           ListHead listItem;

           ListHead hashItem;

     

    private:

           bool setDomainAndDesc(ICQ_STR &name, ICQ_STR &des);

     

           RemoteSession *createSession(uint32 uin);

           void notify(uint32 uin, DB_CALLBACK cb);

     

           void createPacket(TcpOutPacket &out, uint16 cmd);

           TcpOutPacket *createPacket(uint16 cmd);

           void sendPacket(TcpOutPacket *out);

           void sendPendingPacket(int s);

     

           void onPacketReceived(TcpInPacket &in);

           void onHello(TcpInPacket &in);

           void onSendMessage(TcpInPacket &in);

           void onAddFriend(TcpInPacket &in);

           void onDelFriend(TcpInPacket &in);

           void onUserOnline(TcpInPacket &in);

           void onUserOffline(TcpInPacket &in);

           void onUserStatus(TcpInPacket &in);

           void onUpdateContact(TcpInPacket &in);

           void onSearchRandom(TcpInPacket &in);

           void onSearchUIN(TcpInPacket&in);

     

           void onHelloReply(TcpInPacket &in);

           void onAddFriendReply(TcpInPacket &in);

           void onUpdateContactReply(TcpInPacket &in);

           void onSearchRandomReply(TcpInPacket &in);

           void onSearchUINReply(TcpInPacket &in);

     

           char buf[TCP_PACKET_SIZE];

           int bufSize;

     

           ListHead uinHash[UIN_HASH_SIZE];

           ListHead sessionList;

           ListHead sendQueue;

     

           DECLARE_SLAB(Server)

    };

    上面的程序,我不做太多解释,我想大家也应该看得懂,如有疑问可以发表看法,来讨论一下.


    最新回复(0)