海量用户通讯系统-用户注册(2)|学习笔记

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 快速学习海量用户通讯系统-用户注册(2)

开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:海量用户通讯系统-用户注册(2)】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/626/detail/9812


海量用户通讯系统-用户注册(2)

 

目录:

一、common/message/user.go

二、common/message/message.go

三、clientproces/userProcess.

四、在 dieatmain/main.go 增加了代码

五、在 server modeluserDao.go

六、Processor.go

 

一、common/message/user.go

package message

//定义一个用户的结构体

type User struct {

//确定字段信息

//为了序列化和反序列化成功,我们必须保证

//用户信息的json字符串的key 和 结构体的字段对应的 tag 名字一致!!! UserId int `json:"userid"

UserPwd string`json:"userPwd" UserName string `json:"userName"}

 

二、common/message/message.go

package message

const(

LoginmesType "LoginMes"

LoginResMesType "LoginResMes"

RegisterMesType "RegisterMes"

)

type Message struct {

Type string `json:"type"

//消息类型

Data string*json:"data"*

//消息的类型

//定义两个消息..后面需要再增加

type LoginMes struct {

UserId int `json:"userId"

//用户id

UserPwd string `json:"userPwd"*

//用户密码 UserName string `json:"userName""

//用户名

type LoginResMes struct {

Code int*json:"code"*

// 返回状态码500表示该用户未注册 200表示登录成功 Error string `json:"error""

// 返回错误信息

Error  String json :error

//返回错误信息

type Reristerhes struct {

User User

//类型就是User结构体。

}

Code int json: "code-"返回状态码400表示该用户已经占有200表示注册成功

Error string、'json:"error"

//返回错误信息

 

三、clientproces/userProcess.

package process import(

"fmt""net"

"go_code/chatroom/common/message""go code/chatroom/client/utils""encoding/binary"

"encoding/json"

"os"

type UserProcess struct {

//暂时不需要字段..}

func(this *UserProcess)Register(userId int,

userPwd string, userName string)(err error){

//1.链接到服务器

conn, err := net.Dial("tcp","localhost:8889") if err != nil {

fmt.Println("net.Dial err=", err) return

//延时关闭

defer conn.close))

//2,准备通过conn发送消息给服务 var mes message.Message

mes.Type = message.RegisterMesType

//3.创建一个LoginMes 结构体

var registerMes message.RegisterMes registerMes.User.UserId =userId registerMes.User.UserPwd =userPwd registerMes.User.UserName = userName

//4.将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 {

//将mes的Data部分反序列化成 RegisterresMes var registerResMes message.RegisterResMes

err =json.Unmarshal([]byte(mes.Data),®isterResMes) if registerResMes.Code == 200 {

fmt.Println("注册成功,你重新登录一把")

} else {

fmt.Println(registerResMes.Error)

os.Exit(0)

return I

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

//写一个函数,完成登录

func(this *UserProcess) Login(userId int, userPwd string)(err error){

//下一个就要开始定协议.

// fmt.Printf(" userId = %d userPwd=%s\n", userId, userPwd)for true {

fmt.Println("_ ...- ----欢迎登陆多人聊天系统------------"

fmt.Println("\t\t\t 1 登陆聊天室") fmt.Println("\t\t\t 2 注册用户") fmt.Println("\t\tlt3 退出系统") fmt.Println("\t\t\t 请选择(1-3):")

fmt.Scanf("%d\n",&key) switch key

case 1:

fmt.Println("登陆聊天室") fmt.Println("请输入用户的id

fmt.Println("请输入用户的id") fmt.Scanf("%d\n",&userId)

fmt.Println("请输入用户的密码") fmt.scanf("%s\n",&userPwd)

// 完成登录

//1、创建一个UserProcess的实例 up :=&process.UserProcess() up.Login(userId,userPwd) case 2 :

fmt.Println("注册用户")

fmt.Println("请输入用户id:") fmt.Scanf("%d\n",&userId)

fmt.Println("请输入用户密码:" fmt.Scanf("%s\n",&userPwd)

fmt.Println("请输入用户名字(nick):" fmt.scanf("%s\n",&userPwd) case 3 :

fmt.Println("退出系统")

//loop = false os.Exit(e) default :

fmt.Println("你的输入有误,请重新输入")

}

}

//更加用户的输入,

显示新的提示信息

//if key==1{

// / 说明用户要登陆

//fmt.Print1n("请输入用户的id")

7,到这个时候 data就是我们要发送的消息

7.1 先把 data的长度发送给服务器

// 先获取到 data的长度->转成一个表示长度的byte切片

var pkgLen uint32

pkgLen = uint32(len(data)) var buf [4]byte

binary.BigEndian.PutUint32(buf[e:4],pkgLen)

// 发送长度

n,err := conn.Write(buf[:4]) if n != 4 ll err != nil {

fmt.Println("conn.Write(bytes)fail", err) return}

fmt.Printf("客户端,发送消息的长度=%d内容=%s",len(data),string(data))

// 发送消息本身

err = conn.Write(data) if err != nil {

fmt.Println("conn.Write(data)fail",err) return}

//休眠20

time.Sleep(20. timesecond

// fnt.Print1n("休眠了20.")

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

//创建一个Transfer 实例 tf:=&utils.Transfer{

Conn:conn,

mes, err =tf.ReadPkg()

//mes 就是

if err l= ni1 {

fmt.Println("readpkg(conn)err-", err) return}工

//将mes的Data部分反序列化成LoginresMes var loginResMes message.LoginResMes

err =json.Unmarshal([]byte(mes.Data),&loginResMes)

1先把user.go放入到common/message文件夹.

2. common/message/message.go 新增加两个消息类型

3.在客户端接收用户的输入

4.在client/process/userProcess.go 增加一个Register方法,完成请求注册

 

四、在 dieatmain/main.go 增加了代码

godeichatroom Clnentiprocess

//定义两个变量,一个表示用户id,一个表示用户密码 var userid int

var userPwd string var userName string

func main() {

//接收用户的选择 var key int

//判断是否还继续显示菜单

//var loop = trde

 

五、 在 server modeluserDao.go

package model

import(

"fmt"

"github.com/garyburd/redigo/redis" go code/chatroom/common/message"encoding/json"

//我们在服务器启动后,就初始化一个userDao实例,

//把它做成全局的变量,在需要和redis操作时,就直接使用即可 var

MyUserDao *UserDao

//定义一个UserDao 结构体体//完成对User 结构体的各种操作。

type UserDao struct {

pool*redis.Pool

//使用工厂模式,创建一个UserDao实例

func NewUserDao(pool *redis.Pool)(userDao *UserDao){

userDao = &UserDaof

pool pool

return

考一下在UserDao 应该提供哪些方法给我们根据用户id 返回 一个User实例+err

(this *UserDao)getUserById(conn redis.Conn, id int)(user *User, err error)

//通过给定id 去 redis查询这个用户

res, err := redis.string(conn.Do("HGet", "users", id)) if err != nil {

//错误!

if err == redis.ErrNil {

//表示在users 哈希中,没有找到对应id

err = ERROR USER NOTEXISTS}

return

user = &User0)

//这里我们需要把res 反序列化成User实例 err=json.Unmarshal([]byte(res),user) if err != nil {

fmt.Println("json.Unmarshal err=", err) return

}

//完成登录的校验 Login

//1.Login 完成对用户的验证

//2。如果用户的id和pwd都正确,则返回一个user实例//3.如果用户的id或pwd有错误,则返回对应的错误信息

func(this *UserDao) Login(userId int, userPwd string)(user *User, err error){

//先从userDao 的连接池中取出一根连接 conn := this.pool.Get() defer conn.close()

user, err = this.getUserById(conn, userId) if err != nil {

return

//这时证明这个用户是获取到。 if user.UserPwd != userPwd {

err =ERROR_USER_PWD return

return

func (this *UserDao) Register(user *message.User)(err error){

//先从userDao 的连接池中取出一根连接 conn := this.pool.Geto)

err =this.getUserById(conn, user.UserId) if err == ni1 {

err =ERROR USER EXISTS return}

//这时,说明id在redis还没有,则可以完成注册 data,err := json.Marshal(user)//序列化 if err != nil {

return}

//入库

err =conn.Do("HSet", "users", user.UserId, string(data))

日 if err != nil {

fmt.Println("保存注册用户错误 err=",err) return}

return}

//编写一个ServerProcessMes 函数

//功能:根据客户端发送消息种类不同,决定调用哪个函数来处理

func (this *Processor)serverProcessMes(mes *message.Message)(err error){

switch mes.Type {

case message.LoginMesType:

 

六、Processor.go

//处理登录登录

//创建一个UserProcess实例

up :=&process2.UserProcess

Conn :this.conn,}

err =up.ServerProcessLogin(mes) case message.RegisterMesType :

//处理注册

up :=&process2.UserProcess{

Conn :this.Conn,}

err =up.ServerProcessRegister(mes) default :

fmt.Println("消息类型不存在,无法处理...")

return

func(this *Processor)process2()(err error){

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
缓存 前端开发 Go
从4开始,在后端系统中增加用户注册和登录功能
从4开始,在后端系统中增加用户注册和登录功能
21 0
|
JSON 网络协议 NoSQL
海量用户通讯系统-用户注册(1)|学习笔记
快速学习海量用户通讯系统-用户注册(1)
80 0
|
JSON 网络协议 测试技术
海量用户通讯系统-登录(指定用户)|学习笔记
快速学习海量用户通讯系统-登录(指定用户)
73 0
|
NoSQL 网络协议 测试技术
海量用户通讯系统-用户登录(2)|学习笔记
快速学习海量用户通讯系统-用户登录(2)
62 0
|
JSON NoSQL 网络协议
海量用户通讯系统-用户登录(1)|学习笔记
快速学习海量用户通讯系统-用户登录(1)
266 0
|
NoSQL 网络协议 关系型数据库
海量用户通讯系统-完成界面|学习笔记
快速学习海量用户通讯系统-完成界面
131 0
海量用户通讯系统-完成界面|学习笔记
|
JSON 网络协议 测试技术
海量用户通讯系统-项目小结|学习笔记
快速学习海量用户通讯系统-项目小结
101 0
海量用户通讯系统-项目小结|学习笔记
|
机器学习/深度学习 JSON 前端开发
海量用户通讯系统-显示在线用户列表(4)|学习笔记
快速学习海量用户通讯系统-显示在线用户列表(4)
78 0
|
机器学习/深度学习 JSON 网络协议
海量用户通讯系统-显示在线用户列表(3)|学习笔记
快速学习海量用户通讯系统-显示在线用户列表(3)
98 0
|
网络协议 测试技术 Go
海量用户通讯系统-显示在线用户列表(2)|学习笔记
快速学习海量用户通讯系统-显示在线用户列表(2)
59 0