我們?cè)赾tls.Getmessage方法中盐肃,進(jìn)行了一個(gè)defer操作俯艰。
func (m *MessageController) GetMessage() {
defer m.CloseWebSocket()
//...
}
通過(guò)這個(gè)操作,我們可以在用戶斷開之后懂更,進(jìn)行刪除用戶的一些操作湿故。
_, msg, err := m.Conn.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
logs.Error("error: %v", err)
}
break
}
在for循環(huán)體中阿趁,我們判斷如果這個(gè)error是關(guān)閉連接拋出的,那么我們就直接break坛猪,break之后循環(huán)體退出脖阵,函數(shù)結(jié)束,就會(huì)走到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)
}
我們首先執(zhí)行了一下Logout方法命黔,LogOut方法中我們調(diào)用removeFromRedis來(lái)刪除了當(dāng)前用戶的所有操作。
func (l *LoginService) LogOut() (result *returnData) {
result = l.removeFromRedis(l.Index)
return
}
func (l *LoginService) removeFromRedis(index int) (result *returnData) {
//獲取redis實(shí)例
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)
//刪除當(dāng)前用戶所對(duì)應(yīng)的分組
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這個(gè)map中當(dāng)前用戶的連接,并將這個(gè)連接關(guān)閉了悍募。
//CloseWebSocket方法第6行
common.Client = append(common.Client[:m.Index], common.Client[m.Index+1:]...)
m.Conn.Close()
至此用戶的連接已經(jīng)斷開,并且將用戶與我們topic的綁定關(guān)系刪除了洋机。
接下來(lái)坠宴,我們將研究一下用戶發(fā)送消息的方法。