美文网首页
go语言聊天室实现(九)用户断开连接后的操作

go语言聊天室实现(九)用户断开连接后的操作

作者: 公式般欢笑 | 来源:发表于2020-03-22 07:45 被阅读0次

我们在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的绑定关系删除了。

接下来,我们将研究一下用户发送消息的方法。

相关文章

网友评论

      本文标题:go语言聊天室实现(九)用户断开连接后的操作

      本文链接:https://www.haomeiwen.com/subject/svpjehtx.html