go游戏后端开发33:解散房间
接下来,我们来实现房间的解散功能。因为在调试过程中,如果不能取消房间,就需要频繁重启程序,这非常不方便。所以,我们先来实现这个解散功能。
房间解散的流程其实很简单。当发起解散请求后,我们会向所有用户发送一个解散推送。这个推送包含以下信息:房间内所有用户的名称、用户是否同意解散(同意则标记为“true”,不同意则标记为“false”)、用户的座次、倒计时时间、发起解散的用户信息(包括是否在线和头像)。
当所有用户都同意解散时,我们就销毁房间。接下来,我们来具体实现这个功能。我们需要找到之前接收消息的位置,在这里接收一个名为“ask”的消息,消息编号为30313。然后,我们返回一个413的消息。
在解散功能中,我们需要添加一些数据。这里会有一个名为“isAgree”的字段,表示用户是否同意解散。我们还需要判断用户是否同意解散。如果用户同意解散,我们将这个信息添加到数组中。如果不同意,就不添加。
我们还需要对所有用户的同意情况进行统计。如果同意解散的用户数量等于房间内用户总数,那么我们就解散房间。解散房间的操作可以参考之前踢人的操作,直接将所有用户踢出房间。当房间内没有用户时,我们就可以销毁房间了。
在实现过程中,我们还需要给用户发送一个推送消息,通知他们房间解散的情况。这个推送消息需要包含用户ID、头像、是否在线等信息。倒计时时间可以暂时设置为30秒。
接下来,我们来看一下具体实现的代码逻辑。我们需要在合适的位置添加锁,以避免并发问题。在接收解散请求时,我们需要判断是否已经初始化了相关的数据结构。如果没有初始化,我们需要进行初始化操作。
在统计用户同意情况时,我们需要遍历所有用户的响应,将同意解散的用户标记为“true”。如果所有用户都同意解散,我们就执行解散操作。解散操作完成后,我们需要清理相关的数据,以便下次重新创建房间。
在测试过程中,我们发现了一些问题。例如,在解散房间后,无法再次创建房间。这可能是由于我们在解散房间时没有正确清理相关的数据。我们需要检查代码,确保在解散房间后,所有的数据都被正确清理。
另外,我们在实现解散功能时,还需要注意一些细节。例如,在用户同意解散后,我们需要及时更新界面,让用户知道房间已经解散。同时,我们还需要处理用户不同意解散的情况,避免出现逻辑错误。
通过以上步骤,我们完成了房间解散功能的实现。这个功能的实现,使得我们在调试过程中更加方便,可以快速地创建和解散房间,提高了开发效率。
func (r *Room) DismissRoom(session *remote.Session, reason enums.RoomDismissReason) {
if r.TryLock() {
defer r.Unlock()
}
if r.roomDismissed {
return
}
r.roomDismissed = true
//将redis中房间信息删除掉
r.RedisService.Delete(r.Id)
//解散 将union当中存储的room信息 删除掉
r.cancelAllScheduler()
r.createHongBaoList()
// 获取并存储游戏数据
r.recordAllDrawResult(session)
//获取并存储房间的数据
if r.currentUserCount == 0 ||
reason == enums.UnionOwnerDismiss ||
r.RoomCreator.CreatorType == enums.UserCreatorType ||
(reason == enums.UserDismiss && !r.hasFinishedOneBureau) {
var users []*proto.RoomUser
for _, v := range r.users {
users = append(users, v)
}
r.userLeaveRoomNotify(users, session)
r.union.DestroyRoom(r.Id)
r.destroyRoom(reason, session)
r.sendData(proto.RoomDismissPushData(reason), session.GetMsg())
} else {
// 清除掉线玩家
r.clearOfflineUser(session)
if r.currentUserCount == 0 {
r.union.DestroyRoom(r.Id)
r.destroyRoom(reason, session)
return
}
r.notifyUpdateAllUserInfo(session)
r.destroyRoom(reason, session)
r.sendData(proto.RoomDismissPushData(reason), session.GetMsg())
r.resetRoom(session)
}
}