Realization of mobile game disconnection and reconnection

1. The necessity of disconnection and reconnection

In the era of terminal games, because the game environment is relatively fixed, the possibility of disconnection is relatively small, and reconnection after disconnection is not that important. The process of re-login.

But in the case of mobile devices, the environment is very unstable, and the network may also be very unstable. If you follow the early client game practice and go directly to the login process, the user experience will be very bad.

Of course, some judges are disconnected and just connect to the network directly, but it is not that simple. Because the user's operation is uncertain, the user may stay in any interface.

For example: when you enter the elevator while drawing the card, the network is disconnected, then send (draw the card) message to the server, and wait for the connection to the Internet

The server did not receive the card drawing message. At this time, everyone thought about what would happen, and the message was lost. Because the card drawing function is an important system for krypton gold games, art and planning partners hope to make this function more beautiful, which may be completed in several steps. The next step is highly dependent on the return of a message on the server. Any message in the middle It doesn’t matter if it is lost, and there may be various exceptions if it is lost. For client programmers, if they handle this situation specially, it will be ecstasy and painful.

Therefore, we need to implement a once-and-for-all mechanism at the bottom layer to realize the correctness of our messages, and it is particularly important to confirm the correctness of disconnected and reconnected messages.

2. The idea of ​​disconnection and reconnection and pseudo-code implementation

//伪代码,消息的定义
message
{    
    int length;    //消息长度
    short msgId;   //消息ID
    int seq;   //消息序号
    bytes body;    //消息体
}

}

For both client and server, there are two variables sendSeq (locally sent sequence number) and recvSeq (received sequence number)

sendSeq:

        I send the serial number sent actively, and sendSeq++ will be incremented every time a message is sent, and sendSeq will not be updated under special circumstances. Except for messages such as login, reconnection, and heartbeat signals, the specific messages are defined according to the business situation.

recvSeq:

        Record the current serial number received by the other party, if the serial number of message.seq is not 0, it will be recorded;

1) The necessary message sent by the client message each time (the message sequence number will be incremented by sendeq++, and sendSeq will be assigned to message.seq;

2) The customer stores the necessary messages (set a certain length of storage, such as a maximum of 64). If the cache area is greater than the maximum number of cached messages, then delete the earliest cached message to ensure that the maximum number of messages stored in the cache area is not greater than the set set the maximum threshold.

//发送消息处理伪代码函数
function sendMessage(message )
{
    if(消息在忽略列表中)
    {
        message.seq = 0;
    }
    else
    {
       sendSeq++;
       message.seq = sendSeq;
       //缓存到发送列表中
       if(cacheSendList.length>=MAX_CACHE_LENGTH)
          cacheSendList.remove(0);
           
       cacheSendList.add(message);
    }
    
    socket.send(message);
}

3) The client receives the received server-side message, checks message.seq!=0 and updates recvSeq

//收到消息处理伪代码函数
function recv(message)
{
    if(message.seq!=0)
        recvSeq = message.seq;

    //处理消息
    handle(message);
}

4) The same applies to steps 1, 2, and 3 on the server side. The messages filtered by the server's cache include: non-essential message content such as chat, heartbeat, and carousel. The length of its cache needs to be set to be greater than 64, depending on the actual situation.

5) When the client checks that the network is disconnected and needs to trigger disconnection and reconnection, the client disconnection reconnection interface (for example: the network is disconnected during login, does not need to trigger reconnection, just re-login directly, only enter the game disconnected and reconnected), the client sends a LoginReconnectToken message to the server (with verification content such as token content)

//伪代码
LoginReconnectToken
{
    string token;
    string userId;
    //其它内容
    ....
}

6) The server verifies the token and returns BeginReconnect, informs the client to start reconnecting, and sends the recvSeq of the server to the client

//伪代码
BeginReconnect
{
    int32 seq;
    //其他内容
    ...
}

7) The client receives the BeginReconnect message from the server, returns the recvseq received by the client before reconnection to the server through BeginReconnect2, and sends the cached message according to the seq comparison of the current message to reissue the message

BeginReconnect2
{
    int32 seq;
    //其它内容
    ...
   
}

Reissue cache content code:

//发送重连消息伪代码函数,补发的消息序号sendSeq并不需要增加
sendReconnectMessage(seq)
{
    foreach(message:cacheSendList)
    {
        if(message.seq <seq)
            continute;

        socket.send(message);
    }
}

8) The server receives the BeginReconnect2 message from the client, and reissues the message according to the seq contained in the BeginReconnect2 message

9) In this way, the two parties will reconnect

Notice:

  In fact, there will be many special situations in actual use: the network may be disconnected again during reconnection, the network may be disconnected when logging in, the connection times out multiple times, or the serial number has a large difference, such as special processing, server cache optimization, etc. These are all logical problems. , is not the core content of our disconnection and reconnection, so I won’t elaborate here

Guess you like

Origin blog.csdn.net/lejian/article/details/124425730