引言
1、架构图
直接上图
2、Manager定义
2.1 获取session对象
sessionid由客户端cookie存储(其实也可以支持在header自定义或者url传参)
func (manager *Manager) GetSession(w http.ResponseWriter, r *http.Request) (s *Session) {
/*加锁*/
manager.lock.Lock()
defer manager.lock.Unlock()
cookie, err := r.Cookie(manager.CookieName)
if err != nil || cookie.Value == "" {
/*获取sid*/
sid := manager.sessionId()
s = manager.NewSesssion(sid)
cookie := http.Cookie{
Name: manager.CookieName,
Value: url.QueryEscape(sid),
Path: "/",
HttpOnly: true,
MaxAge: manager.maxlifetime,
}
http.SetCookie(w, &cookie)
} else {
sid, _ := url.QueryUnescape(cookie.Value)
s = manager.NewSesssion(sid)
}
return s
}
复制代码
2.2 注册store
func Register(name string, store StoreInterface) {
if store == nil {
log.Panic("Session: Register store is nil")
}
name = strings.ToLower(name)
if _, ok := Stores[name]; ok {
log.Panic("Session: Register store is exist")
}
Stores[name] = store
}
复制代码
3、session定义
type Session struct {
ID string
store StoreInterface
mamager *Manager
ttl int
}
func (s *Session) DestroySession(w http.ResponseWriter, r *http.Request) {
cookie := http.Cookie{
Name: s.mamager.CookieName,
Value: "",
Path: "/",
MaxAge: -1,
}
http.SetCookie(w, &cookie)
}
func (s *Session) Set(key string, value interface{}) error {
return s.store.Set(s.ID, key, value, s.ttl)
}
func (s *Session) Get(key string) (interface{}, error) {
return s.store.Get(s.ID, key)
}
func (s *Session) Delete(key string) error {
return s.store.Remove(s.ID, key)
}
复制代码
4、session_store定义
type StoreInterface interface {
//删除某个key的值
Remove(Sid string, key string) error
//获取某个key的值
Get(Sid string, key string) (interface{}, error)
//设置某个key的值
Set(Sid string, key string, value interface{}, ttl int) error
}
复制代码
5、使用redis实现store
var Ctx context.Context
type RedisStore struct {
reidsClient *redis.Client
}
func NewRedis(addr, password string, db, PoolSize int) *RedisStore {
ClientRedis := redis.NewClient(&redis.Options{
Addr: addr,
Password: password, // no password set
DB: db, // use default DB
PoolSize: PoolSize, // 连接池大小
//MinIdleConns: 5,
})
Ctx = ClientRedis.Context()
err := ClientRedis.Ping(Ctx).Err()
if err != nil {
log.Panic("Cache store redis:", err)
}
return &RedisStore{
reidsClient: ClientRedis,
}
}
func RegisterRedis(addr, password string, db, PoolSize int) {
gosession.Register("redis", NewRedis(addr, password, db, PoolSize))
}
func (s *RedisStore) FmtKey(Sid, key string) string {
return fmt.Sprintf("%s_%s", Sid, key)
}
func (s *RedisStore) Get(Sid, key string) (interface{}, error) {
return s.reidsClient.Get(Ctx, s.FmtKey(Sid, key)).Result()
}
func (s *RedisStore) Set(Sid, key string, value interface{}, d int) error {
return s.reidsClient.Set(Ctx, s.FmtKey(Sid, key), value, time.Duration(d)*time.Second).Err()
}
func (s *RedisStore) Remove(Sid, key string) error {
return s.reidsClient.Del(Ctx, s.FmtKey(Sid, key)).Err()
}
复制代码
6、demo
package main
import (
"fmt"
"log"
"net/http"
"github.com/18211167516/gosession"
"github.com/18211167516/gosession/store"
"github.com/gogf/gf/util/gconv"
)
var GloabSession *gosession.Manager
func init() {
var err error
store.RegisterRedis("192.168.99.100:6379", "", 10, 10)
GloabSession, err = gosession.NewDefaultIDManager("redis", "gosession", 84600)
if err != nil {
log.Panic("Session Manager init ", err)
}
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path)
}
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "URL.PATH=%q\n Header=%q\n", r.URL.Path, r.Header)
}
func login(w http.ResponseWriter, r *http.Request) {
s := GloabSession.GetSession(w, r)
v, _ := s.Get("isLogin")
if gconv.Int(v) == 1 {
fmt.Fprintf(w, "已登录")
} else {
s.Set("isLogin", 1)
fmt.Fprintf(w, "正在登录")
}
}
func logout(w http.ResponseWriter, r *http.Request) {
s := GloabSession.GetSession(w, r)
s.Delete("isLogin")
s.DestroySession(w, r)
fmt.Fprintf(w, "已退出登录")
}
func main() {
http.HandleFunc("/", indexHandler)
http.HandleFunc("/hello", helloHandler)
http.HandleFunc("/login", login)
http.HandleFunc("/logout", logout)
http.ListenAndServe(":8080", nil)
}
复制代码
7、其它
与诸君共勉之,写的不好的地址给指正,希望对您有帮助,思路很重要
近期评论