session存入redis实现持久化
发布于 1 年前 作者 huzhen189 1046 次浏览 来自 分享

介绍 刚刚上手,留个笔记。个人使用的mqantserver的demo,预备开发一个微信对战小游戏,断下重连是必须要有的,所以考虑后session状态准备保存到redis内。 demo中也预留了redis的接口,在/server/game/module.go 中有三个函数

  1. func (gate *Gate) Storage(Userid string, session gate.Session) (err error)
    // 存储用户的Session信息,Session Bind Userid以后每次设置 settings都会调用一次Storage*
    
  2. func (gate *Gate) Delete(Userid string) (err error)
    // 强制删除Session信息
    
  3. func (gate *Gate) Query(Userid string) ([]byte,  error)
    // 获取用户Session信息,用户登录以后会调用Query获取最新信息
    

通过编写这三个接口,可以将session 存入 redis 中,实现持久化

接入redis 这个没什么好说的,在mian.go 的 main()内创建redis的连接对象 _redis, err := redis.Dial(“tcp”, “127.0.0.1:6379”) if err != nil { fmt.Println(“Connect to redis error”, err.Error()) return } db.SetRedis(“default”,_redis);

/db/redis.go  这个文件对redis 做了一下封装,也就是写了一个set和get方法
	package db
	import (
		"github.com/garyburd/redigo/redis"
	)
	var redisArr map[string]redis.Conn =make( map[string]redis.Conn)
	
	func SetRedis(key string,e redis.Conn){
		redisArr[key] = e
	}
	func GetRedis(keys ...string)(e redis.Conn){
		if len(keys)==0{
			return redisArr["default"]
		}else{
			return redisArr[keys[0]]
		}
	}

存入接口编写 – Storage

	func (gate *Gate) Storage(Userid string, session gate.Session) (err error) {
	  log.Info("需要处理对Session的持久化")
	  _redis := db.GetRedis()
	  data, err := session.Serializable()
	  //  \src\github.com\liangdas\mqant\gate\base\session.go
	  //  mqant里面已经做好了对session 的编码和解码,直接使用即可   
	  if err != nil {
		  log.Info("session Serializable error: ", err.Error())
		  return err
	  }
	  _, err = _redis.Do("SET", "session_user_id_"+Userid, data, "EX", "3600");
	  if err != nil {
		  log.Info("redis set failed:", err.Error())
		  return err
	  }
	  return nil
  }

删除接口编写 – Delete

	func (gate *Gate) Delete(Userid string) (err error) {
		log.Info("需要删除Session持久化数据")
		_redis := db.GetRedis()
		_, err = _redis.Do("DEL", "session_user_id_"+Userid)
		if err != nil {
			log.Info("redis del failed:", err.Error())
			return
		}
		return nil
	}

查询接口编写 – Query

  func (gate *Gate) Query(Userid string) ([]byte,  error) {
	  log.Info("查询Session持久化数据")
	  _redis := db.GetRedis()
	  res, err := redis.Bytes(_redis.Do("GET", "session_user_id_"+Userid))
	  if err != nil {
		  log.Info("redis get failed:", err)
		  return nil,err
	  }
	  fmt.Println("redis ------get --------------",res)
	  return res, err
  }

其实也没什么难的,就是mqant对session 存入 redis的格式做了一下限制,使用了proto.Marshal 和 proto.Unmarshal对session 进行了一下处理,刚刚弄的时候不知道,看了一会源码才知道。

2 回复

可以请问一下,在session第一次bind進來時 为什么在使用时会遇到 redis get failed:%!(EXTRA *errors.errorString=redigo: nil returned)

回到顶部