开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:海量用户通讯系统-Redis 添加用户】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/626/detail/9808
海量用户通讯系统-Redis 添加用户
内容简介
一、流程图
二、相关代码
一、流程图
1.processor.go(总的处理器)
(1)根据客户端的请求,调用对应的处理器,完成相应的任务
2.smsProcess.go
(1)处理和短消息相关的请求
(2)群聊,
(3)点对点聊天
3.userProcess.go
(1)处理和用户相关的请求.
(2)登录
(3)注册
(4)注销
(5)用户列表管理
4.model[数据]
user.go
(1)定义一个User结构体
userDao.go
(1)dao: data accessobject
(2)编写对User对象(实例)操作的各种方法。主要就是增删改查.
error.go
(1)自定义错误
Ridis的连接池redis.go
Redis
use----》
100
用户信息str
200
用户信息str
经典项目-海量用户即时通讯系统
实现功能完成用户登录
在Redis手 动添加测试用户,并画图+说明注意(后面通过程序注册用户)
如输入的用户名密码正确在Redis中存在则赛录,否则退出系统,并给出相应的提示信息:
用户不存在或密码错误
你也可以重新注册,再查录
二、相关代码
package model
import
"errors"
moddl/
)
//自定义登录或注册是的错误
var (
ErruserNotExist . errors.New(" user not exist)
ErrXnvlidPasswderrors.New("passwd or .
ErruserExisterrors.New( user exist )
)
package model
//一个用户信息的结构体
type user struct {
userId int" json:“userId"
username string' json: "userName"'
userPud string 'Json:'userPwd'''
var pool redis.Pool
func 1n1tRed1s(addr string, idleConn, naxConn int,sdleTineout time .Duration) {
pool . &redis Pool(
MaxIdle: idleConn,
MaxActive: maxConn,
IdleTineout: idleTimeout,
Dial: func() (redis.Conn, error) (
return redis.D1al("tcp". addr)
}
}
}
func snituserDao() {
model.MyUserDao . nodel.MenUserDao(pool)
func msin()
1/在服务器墙链接到Redis
initredis("localhost:6379" 16, 1024, time*Second 300)
InituserDao()
var (
MyUserDao userDao
)
type UserDao struct (
pool "redis.Pool
}
func NenUserDao(pool redis.Pool)
(userDao *UserDao) (userDao *userDao) {
pool: pool,
}
return
}
func (ud QuserDao) Eetuser(conn redis.Conn,
id int) user User err error) {
result, err : redls.String(conn.Do("MGet", "users", 1d))10err1n11(
if err redis.EcrN1 {
}
err=ErruserNotExist
}
return
err =Json.unmarsnas joyte(resur), user)
if err 1=n11(
return
}
return
func (ud *userDao) Login(id int,
passad string) (user user, err error) {
conn :m ud.pool.Get()
defer conn.close()
user, err . ud. etuser(conn, 1d)
iferr1=n1l{
return
}
user.userPad 1.=passad {
err=ErrInvalidPassad
return
}
return
}
fmt Println("\tlt\t请选择(1-3):")
fmt.scanf(”%d\n", &key)
switch key {
case 1:
fmt . Println("登陆聊天室")
fmt . Print1n("请输入用户的id")
fmt. Scanf("%d\n", &userId)
fmt. Printhn(请输入用户的密码”)
fmt . Scanf("%s\n",&userPwd)
//完成登录
//1.创建一个 userProcess 的实例
up := &process userProcess{}
up.LoginKuserId, userPwd)
cast 2 :
fmt .Printin(在册用户)
//loop = false
case 3 :
fmt.Println("退出系统")
//loop = false
os . Exit(0)
default :
fnt.Pprintln("你的输入有误,请重新输入“)
}
useProcess.go
)
type UserProcess struct {
/暂时不需要字段. .
}
//给关联一个用户登录的方法
//写一个函数, 完成登录
func (this *userProcess) Login(userId int, userPwd string) (err error) {
//下一个就要开始定协议..
// fmt.Printf(" userId = %d userPwd=%s\n", userId, userPwd)
/ return ni1
//1.链接到服务器
conn, err := net.Dial("tcp", "localhost:8889")
if err!=nil{
fmt.PrintIn("net.Dial err=", err)
return
//延时关闭
defer conn. close()
//2.准备通过 conn 发送消息给服务
var mes message Message
mes.Type = message.LoginMesType
//3. 创建一个 LoginMes 结构体
var loginMes message LoginMesloginMes UserId : userId
loginMes UsqrPwd . userPwd
//4. #loginMes 序列化
data, err := json.Marshal(loginMes)iferrl=nilf
fnt.Println("json.Marshal err=", err)return
//创建一个 Transfer 实例
tf := &utils. Transfer{
Conn : conn,
}
mes, err = tf.Readpkg()
// mes 就是
// 5. Jedatalta mes Data7Emes.Data = string(data)
//6.将mes进行序列化化
data, err ! = json.Marshal(mes)
iferrl=nilf
fnt. Println("json.Marshal err=", err)return
17.到这个时候data就是我们要发送的消息
11 7.1 先把 data 的长度发送给服务器
//先获取到 data 的长度->转成-个表示长度的 byte 切片
var pkgLen uint32
//先获取到data的 长度->转成一个表示长度的byte切片
var pkgLen uint32
pkgLen . uint32(1en(data))
var buf [4]byte
binary.B1gEnd an.PutUint32(buf[0:4), pkgLen)
//发送长度
n, err :. conn.Nrite(buf[:4])
ifn!=4 || err!=nil{
fmt.Println("conn.write(bytes) fail", err)
return
}
//fmt. Printf("客服端,发送消息的程度=%d 内容=%s", len(data), string(data))
//发送消息本身
err . conn.Mrite(dat)
If err l-nil l
fmt.Println("conn.rite(data) fall", err)
return
}
//休眠20
//time. sleep(20 . time.Second)
//fmt.Println("休眠了20..")
//这里还需要处理服务器端返回的消息。
//创建一个Transfer实例
tf := &utils. Transfer{
Conn : conn,
}
mes, err = tf.Readpkg()
// mes就是
在Redis手动添加测试用户,并画图+说明注意后面通过程序注册用户)
127.0.0.1:6379>hget users 100
"{\"userId\":100\"userPvd":\ "123456 ", \"userName\":\"\"}"
127 0.0.1:6379) hset users 100 "{\"ues"userId":100. "userPwd":'123456":\"userName"a'scatt\"}"
0
127.0.0.1:6379> hget users 100
"{\"userld":100, userPvd"Ev"123456"\ "userNane "a"scott\") "
127.0.0.1:63797>