我们在ctls.Getmessage方法中,进行了一个defer操作。
func (m *MessageController) GetMessage() {
defer m.CloseWebSocket()
//...
}
通过这个操作,我们可以在用户断开之后,进行删除用户的一些操作。
_, msg, err := m.Conn.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
logs.Error("error: %v", err)
}
break
}
在for循环体中,我们判断如果这个error是关闭连接抛出的,那么我们就直接break,break之后循环体退出,函数结束,就会走到defer方法中。
func (m *MessageController) CloseWebSocket() {
loginService := services.LoginService{
Index: m.Index,
}
result := loginService.LogOut()
fmt.Println(result)
common.Client = append(common.Client[:m.Index], common.Client[m.Index+1:]...)
m.Conn.Close()
fmt.Println("common.client.len:", len(common.Client))
fmt.Println("common.client:", common.Client)
}
我们首先执行了一下Logout方法,LogOut方法中我们调用removeFromRedis来删除了当前用户的所有操作。
func (l *LoginService) LogOut() (result *returnData) {
result = l.removeFromRedis(l.Index)
return
}
func (l *LoginService) removeFromRedis(index int) (result *returnData) {
//获取redis实例
i := strconv.Itoa(index)
client, _ := new(pool.Pool).GetRedisInstance()
defer client.Close()
user_id, _ := client.Do("HGET", services.UserBindRedisKey, i)
fmt.Println("user_id,,,,,,,", user_id)
if user_id==nil{
return
}
user_id = l.B2S(user_id)
fmt.Println("user_id,,,,,,,", user_id, reflect.TypeOf(user_id))
client.Do("HDEL", services.UserBindRedisKey, i)
//删除当前用户所对应的分组
rk := services.RedisKeyUserGroup
rk = strings.Replace(rk, "fd", i, -1)
group, _ := client.Do("GET", rk)
groups := l.B2S(group)
fmt.Println("group is:", reflect.TypeOf(group), group)
client.Do("DEL", rk)
groupArr := strings.Split(groups, "_")
fmt.Println("groupArr================",reflect.TypeOf(groupArr), groupArr)
rk = services.RedisKeyGroupUser
rk = strings.Replace(rk, "first_topic", groupArr[0], -1)
rk = strings.Replace(rk, "second_topic", groupArr[1], -1)
userList, _ := client.Do("GET", rk)
userListArr := strings.Split(l.B2S(userList), ",")
arrIndex:=arrays.Contains(userListArr,user_id)
userListArr=append(userListArr[:arrIndex], userListArr[arrIndex+1:]...)
if len(userListArr)==0{
client.Do("DEL",rk)
}else{
client.Do("SET",rk,strings.Replace(strings.Trim(fmt.Sprint(userListArr), "[]"), " ", ",", -1))
}
//删除fd绑定的用户。
client.Do("HDEL",services.FdBindUserRedisKey,user_id)
return
}
然后我们删除了Cliet这个map中当前用户的连接,并将这个连接关闭了。
//CloseWebSocket方法第6行
common.Client = append(common.Client[:m.Index], common.Client[m.Index+1:]...)
m.Conn.Close()
至此用户的连接已经断开,并且将用户与我们topic的绑定关系删除了。
接下来,我们将研究一下用户发送消息的方法。