瀏覽代碼

save, read session tested

master
Patrick Peng Sun 8 年之前
父節點
當前提交
4167558e07
共有 2 個文件被更改,包括 172 次插入0 次删除
  1. +48
    -0
      chagSession_test.go
  2. +124
    -0
      chatSession.go

+ 48
- 0
chagSession_test.go 查看文件

@@ -0,0 +1,48 @@
package main

import (
"log"
"testing"
"time"
)

func TestSession(t *testing.T) {
id := "testopenid"
state := "testsate"

//delete any existing
deleteSession(id)
path := getSessionPath(id)
AssertEqual(t, isFileExist(path), false, "Session file should not exist")

//create new
setSessionState(id, state, 100)

//wait 1 sec
log.Print("wait for 1 sec for testing timestamp ......")
time.Sleep(1 * time.Second)
log.Print("......waiting done")

//read back , check state
s, _ := getCurrentSesssion(id)
AssertEqual(t, s.State, state, "")
now := int32(time.Now().Unix())

//check timing
AssertEqual(t, s.Expire > now, true, "Expire should be in future")
AssertEqual(t, s.UpdateAt < now, true, "Update should be in pass")
AssertEqual(t, s.CreateAt == s.UpdateAt, true, "Update should be equal to create")
AssertEqual(t, isExpired(now), false, "current time should not be expired")

//update existing session
s, _ = setSessionState(id, state, 100)
//timeing should be exactly 1s diff
AssertEqual(t, s.CreateAt+1 == s.UpdateAt, true, "second Update should be bigger create")
n, _ := getCurrentSesssion(id)
AssertEqual(t, s, n, "session should be equal")

//delete session, for clean up
deleteSession(id)
path = getSessionPath(id)
AssertEqual(t, isFileExist(path), false, "Session file should not exist")
}

+ 124
- 0
chatSession.go 查看文件

@@ -0,0 +1,124 @@
package main

import (
"encoding/json"
"io/ioutil"
"log"
"os"
"path/filepath"
"time"
)

//a state is a alphanumerical string lessthan 128 bytes.

//when messages comes in we need to differentiate what state is this in.
//default state is where command can happen

//where the state is stored,
// in sessions/openID.json

//if there is no such file, we are in default state.

//First state is to record user's name, email, and phone number.
// for individual state
// state/statename/openID.json

var sessionDir = "sessions"
var stateDir = "state"

//openIDSession openID user's session
type openIDSession struct {
State string `json:"State"` //name of the current state alphanumerical string
CreateAt int32 `json:"CreateAt"` //when is this session created
UpdateAt int32 `json:"UpdateAt"` //when is this session updated
Expire int32 `json:"Expire"` //unix timestamp of when this state expires
}

//read sessions/openID.json to check whether its a state for ongoing dialog
func getCurrentSesssion(openID string) (result openIDSession, err error) {
path := getSessionPath(openID)
log.Printf("read session from %s\r\n", path)
body, err := ioutil.ReadFile(path)
if err != nil { //read file error
if isFileExist(path) {
log.Println("Error session reading " + path)
}
return //empty and expired session
}
err = json.Unmarshal(body, &result)
if err != nil {
log.Printf("Session Content [path=%s] not correct: ", path)
}
//we don't check Expire, we give the caller full control on
//how to deal wiht expired session
return
}

func writeSession(openid string, ss openIDSession) (err error) {
path := getSessionPath(openid)
r, err := json.Marshal(ss)
if err == nil {
err = ioutil.WriteFile(path, r, 0600)
if err != nil {
log.Printf("Error writing session %s: \r\n %s \r\n", openid, r)
log.Println(err)
} else {
log.Println("write session to " + path)
}
} else {
log.Printf("Error encoding session %s ", openid)
log.Println(err)
}
return
}

//create if not available
func setSessionState(openID, state string, expireAfter int32) (updatedSession openIDSession, err error) {
s, err := getCurrentSesssion(openID)
now := int32(time.Now().Unix())
if s.CreateAt == 0 {
s.CreateAt = now
}
s.UpdateAt = now
s.State = state
s.Expire = now + expireAfter
err = writeSession(openID, s)
return s, err
}

func isExpired(timestamp int32) bool {
now := int32(time.Now().Unix())
return now > timestamp
}

func getSessionPath(openID string) (path string) {
path = sessionDir + string(os.PathSeparator) + openID + ".json"
ensurePathExist(path)
return path
}

func getStatePath(openID, stateName string) (path string) {
path = stateDir + string(os.PathSeparator) + stateName + string(os.PathSeparator) + openID + ".json"
ensurePathExist(path)
return
}

func ensurePathExist(path string) {
d := filepath.Dir(path)
if !isFileExist(d) {
log.Println("Creating path [" + d + "]")
os.MkdirAll(d, 0700)
}
}

func deleteSession(openID string) {
path := getSessionPath(openID)
if isFileExist(path) {
err := os.Remove(path)
if err != nil {
log.Println(err)
} else {
log.Println("delete session :" + path)
}
}
}

Loading…
取消
儲存