实现功能-实现用户注册

完成注册功能,把用户信息放到redis中

思路
1 先把user.go 放入到common/message 文件夹中
2 common/message/message.go 新增两个消息类型
3 在客户端接收用户输入
4 在client/process/userProcess.go 增加一个Register方法 ,完成请求注册
5 在server/model/userDao.go 增加了一个方法Register方法

实现功能--完成登录时返回当前在线用户

用户登录后,得到当前用户在线列表

思路分析


思路分析

代码

package process

import "fmt"

//因为UserMgr 实例在服务器端有且只有一个
//因为在很多地方,都会使用的到,因此我们将其定义为一个全局变量
var  (
    userMgr *UserMgr
)
type UserMgr struct {
    onlineUsers     map[int]*UserProcess
}

//完成对UserMgr的初始化工作
func init()  {
    userMgr = &UserMgr{onlineUsers:make(map[int]*UserProcess,1024)}
}

//完成对onlineUsers的添加
func (this *UserMgr)AddOnlineUser(up *UserProcess)  {
    this.onlineUsers[up.UserId] = up
}

//删除
func (this *UserMgr)DelOnlineUser(userId int) {
    delete(this.onlineUsers, userId)
}

//返回当前所有的在线的用户

func (this *UserMgr)GetAllOnlineUsers() map[int]*UserProcess {
    return this.onlineUsers
}

//根据ID  返回对应的值

func (this *UserMgr)GetOnlineUserById(userId int)(up *UserProcess,err error)  {
    //如何从map中取出一个值
    up,ok := this.onlineUsers[userId]
    if !ok{  //说明 你要查找的用户当前不在线
        err = fmt.Errorf("用户%d 不在线",userId)
        return
    }
    return
}

server/process/userMgr.go

package process

import (
    "awesomeProject/chatroom/client/utils"
    "awesomeProject/chatroom/common/message"
    "encoding/binary"
    "encoding/json"
    "fmt"
    "net"
    "os"
)

type UserProcess struct {
    //暂时不需要字段。。。。

}

func (this *UserProcess)Register(usrId int,usrpwd string,usrName string) (err error) {
    conn,err := net.Dial("tcp","localhost:8889")
    if err!=nil{
        fmt.Println("net Dail err=",err)
        return
    }
    //延时关闭
    defer conn.Close()

    var mes message.Message
    mes.Type = message.RegisterMesType
    //3 创建一个LoginMes 结构体
    var registerMes message.RegisterMes
    registerMes.User.UserId = usrId
    registerMes.User.UserPwd = usrpwd
    registerMes.User.UserName = usrName

    //将 registerMes  序列化
    data,err := json.Marshal(registerMes)
    if err!=nil{
        fmt.Println("json marshal err=",err)
        return
    }

    //5  把data赋给  mes.data 字段
    mes.Data = string(data)


    // 6 将mes 进行序列化

    data,err = json.Marshal(mes)
    if err!= nil{
        fmt.Println("json marshal err=",err)
        return
    }

    //创建一个Transfer实例
    tf := &utils.Transfer{
        Conn:conn,
    }
    //发送data给服务器端
    err = tf.WritePkg(data)
    if err != nil{
        fmt.Println("注册发送信息错误  err=",err)
    }

    mes,err = tf.ReadPkg() //mes  就是registerMes

    if err != nil{
        fmt.Println("readpkg err=",err)
        return
    }

    //将mes的data部分反序列化为 registermes
    var registerResMes message.RegisterResMes
    err = json.Unmarshal([]byte(mes.Data),&registerResMes)
    if registerResMes.Code == 200 {
        fmt.Println("注册成功  从新登陆")
        os.Exit(0)

    }else {
        fmt.Println(registerResMes.Error)
        os.Exit(0)

    }
    return
}

//给关联一个用户登录的方法


func (this *UserProcess)Login(usrId int,usrpwd string)(err error)  {
    ////下一步要开始定协议
    //fmt.Printf("userId= %d   usrpwd=%s\n",usrId,usrpwd)
    //return nil
    conn,err := net.Dial("tcp","localhost:8889")
    if err!=nil{
        fmt.Println("net Dail err=",err)
        return
    }
    //延时关闭
    defer conn.Close()

    //2 通过conn发送消息给服务
    var mes message.Message
    mes.Type = message.LoginMesType
    //3 创建一个LoginMes 结构体
    var LoginMes message.LoginMes
    LoginMes.UserId = usrId
    LoginMes.UserPwd = usrpwd
    //4 将loginMes 序列化
    data,err := json.Marshal(LoginMes)
    if err!=nil{
        fmt.Println("json marshal err=",err)
        return
    }
    //5  把data赋给  mes.data 字段
    mes.Data = string(data)

    // 6 将mes 进行序列化

    data,err = json.Marshal(mes)
    if err!= nil{
        fmt.Println("json marshal err=",err)
        return
    }
    //7 这个时候data 就是我们要发送的数据
    //7.1  先把data的长度发送给服务器
    // 先获得到 data的长度-》转成一个表示长度的byte切片
    var pkgLen uint32
    pkgLen = uint32(len(data))
    var buf [4]byte
    binary.BigEndian.PutUint32(buf[0:4],pkgLen)
    //发送长度
    n,err := conn.Write(buf[:4])
    if err!=nil||n != 4 {
        fmt.Println("conn write err=",err)
        return
    }
    fmt.Printf("客户端,发送消息长度ok  有%d 字节 %s",len(data),string(data))

    // 发送消息本身
    _,err = conn.Write(data)
    if err != nil{
        fmt.Println("conn write err=",err)
        return
    }

    //这里还需要处理服务器端返回的消息

    //创建一个Transfer 实例
    tf := &utils.Transfer{
        Conn: conn,
    }
    mes,err = tf.ReadPkg()

    if err != nil{
        fmt.Println("readpkg err=",err)
        return
    }


    //将mes的data部分反序列化为 LoginResMes
    var loginResMes message.LoginResMes
    err = json.Unmarshal([]byte(mes.Data),&loginResMes)
    if loginResMes.Code == 200 {
        fmt.Println("用户登录成功")
        //可以显示当前在线用户列表,遍历loginResmes.UserId
        fmt.Println("当前在线用户列表如下")
        for _,v := range loginResMes.UsersId{
            //如果我们要求不显示自己在线  我们增加下边一段代码
            if v == usrId{
                continue
            }
            fmt.Println("用户ID:\t",v)
        }

        fmt.Println("\n\n")

        //这里我们还需要启动一个协程
        //该协程保持和服务器通讯  如果服务器有数据推送给客户端
        //则接收并显示在客户端的终端
        go serverProcessMes(conn)

        // 1 显示登录成功的菜单  循环
        for  {
            ShowMenu()
        }
    }else {
        fmt.Println(loginResMes.Error)
    }
    return
}

client/process/userProcess.go


当一个新的用户上线后,其他已经登录的用户也能获取最新的在线用户列表

思路
1 当有一个用户上线后,服务器马上把维护的onlineUser map 整体推送
思路2
2 服务器有自己策略,每隔一段时间,把维护的onlineUsermap整体推送

思路3

  • 当一个用户A上限后,服务器就把A用户的上线信息,推送给所有的在线用户
  • 客户端也需要维护一个map,map中记录了他的好友,目前是所有人
    map[int]User
  • 客户端和服务器的通讯通道,要依赖于serverProcessMes 协程
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容