When a user clicks on the “close” button in the client, it triggers the player logout functionality. In the case of an online player logging out, other players should see the offline player disappear from their own client interfaces. The specific process is shown in Figure 18.1.

Figure 18.1

Player Logout is achieved using the SyncPid protocol message with MsgID 201. The trigger for this process occurs just before the client disconnects from the server. By registering the player logout business logic in the hook method before the connection is lost within the Zinx framework, this functionality can be implemented.

When starting the server, register the hook method before the connection is lost, as shown below:

//mmo_game/server.go

func main() {

// Create a server instance
s := znet.NewServer()

// Register the hook function after client connection is established
s.SetOnConnStart(OnConnectionAdd)

// New: Register the hook function before client connection is lost
s.SetOnConnStop(OnConnectionLost)

// Register routers
s.AddRouter(2, &api.WorldChatApi{})
s.AddRouter(3, &api.MoveApi{})

// Start the server
s.Serve()
}

The implementation of the OnConnectionLost() method is as follows:

//mmo_game/server.go

// Hook function when a client disconnects
func OnConnectionLost(conn ziface.IConnection) {

// Get the current connection's Pid attribute
pid, _ := conn.GetProperty("pid")

// Get the corresponding player object based on pid
player := core.WorldMgrObj.GetPlayerByPid(pid.(int32))

// Trigger the player logout business logic
if pid != nil {
player.LostConnection()
}

fmt.Println("====> Player ", pid, " left =====")
}

OnConnectionLost() is called before the connection is lost. First, it retrieves the Pid of the current connection, then it gets the corresponding Player object, and finally, it calls the Player’s LostConnection() method. Here’s the implementation of the LostConnection() method for the Player:

Now we need to provide a LostConnection() method in the player module.

//mmo_game/core/player.go

// Player logout
func (p *Player) LostConnection() {

// 1. Get players in the surrounding AOI nine-grid
players := p.GetSurroundingPlayers()

// 2. Assemble MsgID 201 message
msg := &pb.SyncPid{
Pid: p.Pid,
}

// 3. Send the message to surrounding players
for _, player := range players {
player.SendMsg(201, msg)
}

// 4. Remove the current player from the AOI in the world manager
WorldMgrObj.AoiMgr.RemoveFromGridByPos(int(p.Pid), p.X, p.Z)
WorldMgrObj.RemovePlayerByPid(p.Pid)
}

he LostConnection() method of the Player first retrieves information about all surrounding players, then sends the SyncPid protocol message with MsgID 201 to each online player’s client, and finally removes the current player’s information from the world manager.

Next, start the server and launch two clients to test the results, as shown in Figure 18.2.

Figure 18.2

In the image, we have Player_4 and Player_3. Before Player_4 clicks the “Exit” button, both players can see each other in their respective client interfaces, as shown in Figure 21.19. However, after Player_4 clicks the “Exit” button, the result is as shown in Figure 18.3.

Figure 18.3

From the program’s behavior, it’s evident that Player_3 can no longer see the character information of Player_4 in their field of view. This indicates that when one client logs out, the player on the map of the other client gets removed.

--

--