开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:海量用户通讯系统-用户登录(2)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/626/detail/9810
海量用户通讯系统-用户登录(2)
目录:
一、编写 model/user.go
二、编写 modelerror.go
三、编写 mode/useDaogo
四、编写 mode/的redis.go
五、编写 mode/的Main.go
六、在 proess/userProcessgo 使用到 redis 验证的功能
一、编写 model/user.go
User.go
package model
//定义一个用户的结构体
type User struct {
//确定字段信息
//为了序列化和反序列化成功,我们必须保证
//用户信息的json字符串的key 和 结构体的字段对应的 tag 名字一致!!!
UserId int `json:"userId"
UserPwd string
“
json:"userPwd"
UserName string
“
json:"userName""
二、编写 modelerror.go
Error.go
package model
Import (
"errors"
//根据业务逻辑需要,自定义一些错误,
var
ERROR_ USER _NOTEXISTS = errors.New("用户不存在..”) ERROR_USER_EXISTS =errors.New("用户已经存在...")
ERROR USER PWD =erros.New("密码不正确")
)
三、编写 mode/useDaogo
useDaogo
package model
import(
"fmt"
"github.com/garyburd/redigo/redis" /"encoding/json")
//定义一个UserDao 结构体体
//完成对User 结构体的各种操作。
type UserDao struct {
pool*redis.Pool
//在登录的时候,从那个登录函数里去调查,最后要返回两个信息一个就是user的反馈,一个是user类型,来一个引用也可以。
//就是我们假设有了接口,这个连接有ID了就是通过给定的ID去redis里面去查询用户。操作的时候,有了连接,其实就已经可以做事情了。
//从redis获取了一个pool,获取了以前最原始的时候,操作redis里面拿一个连接,是拨号拿到的,这个类型,应该是redis里面的跟网络连接是不一样的,现在有这个连接过后,调查的一个方法叫do。
//思考一下在UserDao 应该提供哪些方法给我们
//1.根据用户id 返回一个User实例+err
func (this *UserDao) getUserbyidiconn red1s.conn
dint fuser tUse
//通过给定id 去 redis查询这个用户
res, err i= redis.string(conn.Do("HGet", "users", id)) if err != nil
//错误!
if err == redis.ErrNil {
//表示在 users 哈希中,没有找到对应id
err = ERROR USER NOTEXISTS}
return
user = &User{))
//这里我们需要把res 反序列化成User实例
err =json.Unmarshal([]byte(res),user) if err != nil {
fmt.Println("json.Unmarshal err=", err) return
Return
}
//完成登录的校验 Login
//1.Login 完成对用户的验证
//2.如果用户的id和pwd都正确,则返回一个user实例
//3.如果用户的id或pwd有错误,则返回对应的错误信息
func(this *UserDao) Login(userId int, userPwd string)(user *User, err error){
//先从UserDao 的连接池中取出一根连接
//通过,传一个ID号,可以把user返回去,但有的话就返回,没有的话,其实返回的error,
//最关键的是它能够处理一个登陆的请求,完成登录的校验。
//定义函数,如果用户存在,并且密码也是正确的,也返回一个user,如果,不成功的话,就返回一个错误信息,当然这个user肯定是一个是个空,因为这个时候它涉及到业务逻辑里面去了,肯定是要被别地方来调用的,因此这个函数的首字母,应该大写。
第一点,完成的是对用户的校验,如果用户名密码正确,ID和密码都正确,则返回一个user对象,User实例,但是这个错误就没有了,第二个,如果有错误,有好几种情况,就是说如果他不正确,如果用户的ID或者密码有错,但不知道是哪个有错,或者密码有错,那么则返回一个错误信息。
//首先,写login。什么样信息才能验证呢,显然,应该给用户的ID号和密码,那就是userid,名字,都保持一致,id是一个int类型的,另外一个,它有一个密码,密码是WD。这个时候,它是一个字符串,那么如果是有问题或者没有问题,返回的都是这样一个信息,保持一已经编写了一个get user by ID,在这个包包里面有这个东西,所以第一件事情,从里面先取一根连接出来,userdao连接池。从连接池中取出,取出一根连接。
conn := this.pool.Get()
defer conn.close))
user, err = this.getUserById(conn, userid) if err l= nil {
Return
}
//这时证明这个用户是获取到。
if user.UserPwd != userPwd{
err = ERROR_USER_PWD return
}
Return
}
package main import
"github.com/garyburd/redigo/redis"time"
//定义一个全局的pool var pool *redis.Pool
func initpool(address string, maxidle, maxActive int, idleTimeout time.Duration)
pool= &redis.Pool{
MaxIdle:maxIdle,
//最大空闲链接数
MaxActive: maxActive,
// 表示和数据库的最大链接数, 表示没有限制 IdleTimeout:idleTimeout,
//最大空闲时间
Dial:func()(redis.Conn,error){
// 初始化链接的代码, 链接哪个ip的redis return redis.Dial("tcp", address)}
搜索
qithub 开源项目欢迎有能力(翻译)的同学贡献有何意见也可任意提出
子目录
标准库其它包
子代码库社区
标准库
名称摘要
archive
tartar包实现了tar格式压缩文件的存取
zipzip包提供了zip档案文件的读写服务
bufiobufio 包实现了带缓存的/0操作
builtinbuiltin包为Go的预声明标识符提供了文档
bytesbytes包实现了操作]byte的常用面数
compress
bzip2bzip2包实现bzip2的解压缩
fate
flate包实现了deflate压缩数据格式,参贝RFC1951
gzipgzip包实现了gzip格式压缩文件的读写,参见RFC1952
lzwIzw包实现了Lempel-Ziv-Welch数据压编格式,这是一种TAWelch在A Technique for Hiah-Performance
Data Compression"一文(Computer17(6)(June 1984)pp8-19)提出的一种压缩格式
typeuration
type Duration int64
Duration类型代表两个时间点之间经过的时间,以纳秒为单位。可表示的最长时间段大约290年。
const(
NanosecondDuration-1
Microsecond.1000. Nanosecond
Millisecond.1000* Microsecond
Second. 1000* Millisecond
Minute:60. Second
Hour.60. Minute
常用的时间般。没有定义一天或超过一天的单元,以避免夏时制的时区切换的混乱要将Duration提形值表示为其时间单元的个数,用除法:
second . time.Second
fnt.Printfinto4fsecond/tine.Millisecond))// prints lece
要将整数个某时间单元表示为Duration类型值,用乘法:
seconds 10
fmt.Print(time.Duration(seconds)*time.Second)
// prints 105
Example