我在後端使用golang,mongodb是我的數據庫。 我想將我的web應用程序的用戶會話(在登錄和註銷之間)存儲在mongodb中以進行持久化。由於提供者僅適用於mysql而不適用於mongodb,因此我編輯它以支持mongodb.But,當我嘗試使用它即時得到無效的內存地址或零指針解除引用。 的代碼如下,請,如果有什麼更好的辦法來編碼,請讓我know.Thanks在mongodb golang中保存會話
type (
SessionStore struct {
c *mgo.Session
sid string
lock sync.RWMutex
values map[interface{}]interface{}
}
)
var mgopder = &Provider{}
func (st *SessionStore) Set(key, value interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
st.values[key] = value
return nil
}
// Get value from mongodb session
func (st *SessionStore) Get(key interface{}) interface{} {
st.lock.RLock()
defer st.lock.RUnlock()
if v, ok := st.values[key]; ok {
return v
}
return nil
}
// Delete value in mongodb session
func (st *SessionStore) Delete(key interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
delete(st.values, key)
return nil
}
// Flush clear all values in mongodb session
func (st *SessionStore) Flush() error {
st.lock.Lock()
defer st.lock.Unlock()
st.values = make(map[interface{}]interface{})
return nil
}
// SessionID get session id of this mongodb session store
func (st *SessionStore) SessionID() string {
return st.sid
}
// SessionRelease save mongodb session values to database.
// must call this method to save values to database.
func (st *SessionStore) SessionRelease(w http.ResponseWriter) {
defer st.c.Close()
b, err := session.EncodeGob(st.values)
if err != nil {
return
}
st.c.DB("Employee").C("Sessions").Update(nil, bson.M{"$set": bson.M{
"session_data": b,
"session_expiry": time.Now().Unix(),
"session_key": st.sid,
},
},
)
/*st.c.Exec("UPDATE "+TableName+" set `session_data`=?, `session_expiry`=? where session_key=?",
b, time.Now().Unix(), st.sid)*/
}
type Provider struct {
maxlifetime int64
savePath string
Database string
}
// connect to mongodb
func (mp *Provider) connectInit() *mgo.Session {
ds, err := mgo.Dial("Employee")
if err != nil {
return nil
}
return ds
}
// SessionInit init mongodb session.
// savepath is the connection string of mongodb
func (mp *Provider) SessionInit(maxlifetime int64, savePath string) error {
mp.maxlifetime = maxlifetime
mp.savePath = savePath
mp.Database = "Employee"
return nil
}
// SessionRead get mysql session by sid
func (mp *Provider) SessionRead(sid string) (session.Store, error) {
var sessiondata []byte
ds := mp.connectInit()
defer ds.Close()
c := ds.DB(mp.Database).C("Session")
err := c.Find(bson.M{
"session_key": sid,
}).Select(bson.M{"session_data": 1}).All(&sessiondata)
if err != nil {
if err.Error() == "not found" {
c.Insert(bson.M{
"session_key": sid,
"session_data": " ",
"session_expiry": time.Now().Unix(),
})
}
}
var kv map[interface{}]interface{}
if len(sessiondata) == 0 {
kv = make(map[interface{}]interface{})
} else {
kv, err = session.DecodeGob(sessiondata)
if err != nil {
return nil, err
}
}
rs := &SessionStore{c: ds, sid: sid, values: kv}
return rs, nil
}
// SessionExist check mongodb session exist
func (mp *Provider) SessionExist(sid string) bool {
var sessiondata []byte
ds := mp.connectInit()
defer ds.Close()
c := ds.DB("Employee").C("Sessions")
err := c.Find(bson.M{
"session_key": sid,
}).Select(bson.M{
"session_data": 1,
}).One(&sessiondata)
if err != nil {
if err.Error() == "not found" {
return false
}
}
return true
}
// SessionRegenerate generate new sid for mysql session
func (mp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
var sessiondata []byte
ds := mp.connectInit()
defer ds.Close()
c := ds.DB("Employee").C("Sessions")
err := c.Find(bson.M{
"session_key": oldsid,
}).Select(bson.M{
"session_data": 1,
}).One(&sessiondata)
if err != nil {
if err.Error() == "not found" {
c.Insert(bson.M{
"sessoin_key": oldsid,
"session_data": " ",
"session_expiry": time.Now().Unix(),
})
}
}
/* row := c.QueryRow("select session_data from "+TableName+" where session_key=?", oldsid)
err := row.Scan(&sessiondata)
c.Update(bson.M{"sessoin_key": oldsid}, bson.M{
"$set": bson.M{
"session_key": sid,
},
})
/*c.Exec("update "+TableName+" set `session_key`=? where session_key=?", sid, oldsid)
*/
var kv map[interface{}]interface{}
if len(sessiondata) == 0 {
kv = make(map[interface{}]interface{})
} else {
kv, err = session.DecodeGob(sessiondata)
if err != nil {
return nil, err
}
}
rs := &SessionStore{c: ds, sid: sid, values: kv}
return rs, nil
}
// SessionDestroy delete mysql session by sid
func (mp *Provider) SessionDestroy(sid string) error {
ds := mp.connectInit()
defer ds.Close()
c := ds.DB("Employee").C("Sessions")
c.Remove(bson.M{
"session_key": sid,
})
return nil
}
// SessionGC delete expired values in mysql session
func (mp *Provider) SessionGC() {
ds := mp.connectInit()
defer ds.Close()
c := ds.DB("Employee").C("Sessions")
c.Remove(bson.M{
"session_expiry": bson.M{
"$lt": time.Now().Unix() - mp.maxlifetime,
},
})
return
}
// SessionAll count values in mysql session
func (mp *Provider) SessionAll() int {
var total int
ds := mp.connectInit()
defer ds.Close()
c := ds.DB("Employee").C("Sessions")
total, err := c.Count()
if err != nil {
return 0
}
return total
}
func init() {
session.Register("mongodb", mgopder)
}
錯誤:
panic: runtime error: invalid memory address or nil pointer dereference
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x0 pc=0x6db254]
goroutine 6 [running]:
panic(0xa2f560, 0xc0820080b0)
C:/Go/src/runtime/panic.go:481 +0x3f4
gopkg.in/mgo%2ev2.(*Session).Close(0x0)
C:/Projects/Go/src/gopkg.in/mgo.v2/session.go:1612 +0x144
panic(0xa2f560, 0xc0820080b0)
C:/Go/src/runtime/panic.go:443 +0x4f7
gopkg.in/mgo%2ev2.(*Session).acquireSocket(0x0, 0xc082290000, 0x0, 0x0, 0x0)
C:/Projects/Go/src/gopkg.in/mgo.v2/session.go:4409 +0x4ba
gopkg.in/mgo%2ev2.(*Collection).writeOp(0xc082279f30, 0x8feb80, 0xc082326060, 0xc082326001, 0x0, 0x0, 0x0)
C:/Projects/Go/src/gopkg.in/mgo.v2/session.go:4604 +0xe7
gopkg.in/mgo%2ev2.(*Collection).Remove(0xc082279f30, 0x9d4700, 0xc082326030, 0x0, 0x0)
C:/Projects/Go/src/gopkg.in/mgo.v2/session.go:2586 +0x15c
sample/models.(*Provider).SessionGC(0xe2f5a0)
C:/Projects/Go/src/sample/models/model.go:234 +0x3dc
github.com/astaxie/beego/session.(*Manager).GC(0xc082258b20)
C:/Projects/Go/src/github.com/astaxie/beego/session/session.go:271 +0x48
created by github.com/astaxie/beego.registerSession
C:/Projects/Go/src/github.com/astaxie/beego/hooks.go:68 +0x31d
我很抱歉,需要在mongodb中存儲用戶會話(在我的web應用程序的登錄和註銷之間)以及獨特的會話ID ...請讓我知道如何去做。謝謝.... –
@RajeshKumar我更新了我的答案,請看看 –
感謝mario,.Changed it.But還面臨同樣的錯誤problem.thanks ... –