/** 定时tick,把数据写入文件 **/ func EntityDump(tickTime time.Duration) { c := time.Tick(tickTime * time.Second) for _ = range c { // Utils.LogInfo("%v\n", now) //如果在规定时间内没有更改,就不更新 if dataChange == false { continue } //得到存储方式的句柄 fd := DataStore.GetFd().(*os.File) //清空文件 fd.Truncate(0) //得到gob转换出来的[]byte var wbuf bytes.Buffer egob := gob.NewEncoder(&wbuf) Utils.LogInfo("gob data=%#v\n", TaskData) err := egob.Encode(TaskData) if err != nil { Utils.LogInfo("data gob err") Utils.LogErr(err) continue } _, err = DataStore.Set(wbuf.Bytes()) if err != nil { Utils.LogErr(err) continue } dataChange = false } }
/** 取出readyData和waitData数据 **/ func GetData() (*Entity.ReadyData, *Entity.WaitData, error) { //得到存储方式的句柄 fd := DataStore.GetFd().(*os.File) //得到文件状态 fileStat, err := fd.Stat() if err != nil { return nil, nil, Utils.LogErr(err) } //如果文件是空的,直接返回 fileSize := fileStat.Size() if fileSize == 0 { return &Entity.ReadyData{}, &Entity.WaitData{}, nil } //得到文件大小的buf dataBuf := make([]byte, fileSize) //得到文件读取buf bufReader := DataStore.Get() _, err = bufReader.Read(dataBuf) Utils.LogInfo("read file data=%#v\n", dataBuf) if err != nil { Utils.LogInfo("err=%d\n", err) return nil, nil, err } //吧读到的[]byte转换成结构数据,使用全局变量TaskData rgob := gob.NewDecoder(bytes.NewBuffer(dataBuf)) err = rgob.Decode(&TaskData) Utils.LogInfo("gob data =%v\n", TaskData) if err != nil { Utils.LogInfo("gob data err=%d\n", err) return nil, nil, Utils.LogErr(err) } return TaskData.ReadyData, TaskData.WaitData, nil }
/** 返回所有任务索引数组 **/ func GetAllTaskIndex() ([]Entity.TaskAddr, error) { bufReader := IndexStore.Get() var gobTypeList []Entity.TaskAddr for { var gobType Entity.TaskAddr dataLenBuf := make([]byte, 4) //得到数据体长度 _, err := bufReader.Read(dataLenBuf) if err != nil { Utils.LogInfo("err=%d\n", err) if err == io.EOF { break } return nil, err } dataLen := Utils.BytesToUint32(dataLenBuf) dataBuf := make([]byte, dataLen) _, err = bufReader.Read(dataBuf) Utils.LogInfo("read file index=%#v\n", dataBuf) if err != nil { Utils.LogInfo("err=%d\n", err) return nil, err } rgob := gob.NewDecoder(bytes.NewBuffer(dataBuf)) err = rgob.Decode(&gobType) if err != nil { Utils.LogInfo("gob index err=%d\n", err) return nil, Utils.LogErr(err) } gobTypeList = append(gobTypeList[:], gobType) } Utils.LogInfo("retn index=%#v\n", gobTypeList) return gobTypeList, nil }
/** 写入索引 **/ func AddIndex(dataAddr Entity.TaskAddr) (int, error) { //得到存储方式的句柄 fd := IndexStore.GetFd().(*os.File) //得到文件状态 fileStat, err := fd.Stat() if err != nil { return 0, Utils.LogErr(err) } // //得到文件大小,这个位置就是这条记录的起始位置 dataAddr.FileAddr = fileStat.Size() dataAddr.EleAddr = nil gob.Register(dataAddr) //得到gob转换出来的[]byte var wbuf bytes.Buffer egob := gob.NewEncoder(&wbuf) Utils.LogInfo("gob index=%#v\n", dataAddr) err = egob.Encode(dataAddr) if err != nil { Utils.LogInfo("index gob err") return 0, Utils.LogErr(err) } //拼出最终存入文件的数据==数据长度+数据体 var storeByte []byte storeByteBuf := bytes.NewBuffer(storeByte) //写入数据长度 _, err = storeByteBuf.Write(Utils.Uint32ToBytes(uint32(wbuf.Len()))) if err != nil { return 0, Utils.LogErr(err) } _, err = storeByteBuf.Write(wbuf.Bytes()) if err != nil { return 0, Utils.LogErr(err) } wData := storeByteBuf.Bytes() Utils.LogInfo("len=%d\n", storeByteBuf.Len()) Utils.LogInfo("data=%#v\n", wData) writeNum, err := IndexStore.Set(wData) if err != nil { return 0, Utils.LogErr(err) } return writeNum, nil }
func (tc *TConn) ReadInt(num int) (int, error) { data, err := tc.Read(num) if err != nil { return 0, err } retn, err := strconv.Atoi(strings.Trim(string(data), "\r\n\t ")) if err != nil { return 0, Utils.LogErr(err) } return retn, nil }
func main() { tcpAddr, err := net.ResolveTCPAddr("ip4", ":9800") Utils.LogErr(err) listener, err := net.ListenTCP("tcp", tcpAddr) Utils.LogErr(err) i := 0 readyData, waitData, err := Handle.LoadTask(Config.GetDataFile()) if err != nil { Utils.LogErr(err) return } log.Println("load data=%v", readyData) for key, value := range *readyData { log.Printf("load ready key=%s, data=%v\n", key, value) } for key, value := range *waitData { log.Printf("load wait key=%s, data=%v\n", key, value) } // taskList := make([]Entity.Task, Config.GetRoomMaxNum()) runtime.GOMAXPROCS(runtime.NumCPU()) //go 程处理数据写入文件 go Store2.EntityDump(Config.GetTickTime()) //go程处理waittask检索 go Handle.CheckWaitTask(readyData, waitData) go signalHandle() for { conn, err := listener.Accept() if err != nil { Utils.LogErr(err) return } go Handle.HandleClient(readyData, waitData, conn) // go Handle.Test(i,roomList, conn) // roomChan <- roomList i++ } }
/** 写入任意数据,都使用gob存入file,返回的int64,是该数据在文件中的起始位置 **/ func AddData(data Entity.TaskData) (int, error) { //得到存储方式的句柄 fd := DataStore.GetFd().(*os.File) //得到文件状态 fileStat, err := fd.Stat() if err != nil { return 0, Utils.LogErr(err) } data.FileAddr = fileStat.Size() //得到gob转换出来的[]byte var wbuf bytes.Buffer egob := gob.NewEncoder(&wbuf) Utils.LogInfo("gob data=%#v\n", data) err = egob.Encode(data) if err != nil { Utils.LogInfo("data gob err") return 0, Utils.LogErr(err) } //拼出最终存入文件的数据==数据长度+数据体 var storeByte []byte storeByteBuf := bytes.NewBuffer(storeByte) //写入数据长度 _, err = storeByteBuf.Write(Utils.Uint32ToBytes(uint32(wbuf.Len()))) if err != nil { return 0, Utils.LogErr(err) } _, err = storeByteBuf.Write(wbuf.Bytes()) if err != nil { return 0, Utils.LogErr(err) } wData := storeByteBuf.Bytes() Utils.LogInfo("len=%d\n", storeByteBuf.Len()) Utils.LogInfo("data=%#v\n", wData) writeNum, err := DataStore.Set(wData) if err != nil { return 0, Utils.LogErr(err) } return writeNum, nil }
func main() { service := ":843" tcpAddr, err := net.ResolveTCPAddr("ip4", service) Utils.LogErr(err) listener, err := net.ListenTCP("tcp", tcpAddr) Utils.LogErr(err) i := 0 runtime.GOMAXPROCS(runtime.NumCPU()) for { conn, err := listener.Accept() if err != nil { Utils.LogErr(err) return } Utils.LogInfo("start conn\n") go sendPolicy(conn) // go Handle.Test(i,roomList, conn) // roomChan <- roomList i++ } }
/** 减少时间 **/ func DecExpired(readyData *Entity.ReadyData, waitData *Entity.WaitData, key string, expired uint) error { //如果任务已经在ready中,就不需要处理 if readyData.Isset(key) { return nil } //在wait队列中的,只更新到期时间 if waitData.Isset(key) { waitData.DecExpired(key, expired) //存储数据 Store.SetData(readyData, waitData) return nil } return Utils.LogErr(1001) }
/** 删除一个任务,在两个列表里删,ready和wait **/ func Del(readyData *Entity.ReadyData, waitData *Entity.WaitData, key string) error { if readyData.Isset(key) { readyData.Del(key) //存储数据 Store.SetData(readyData, waitData) return nil } if waitData.Isset(key) { waitData.Del(key) //存储数据 Store.SetData(readyData, waitData) return nil } return Utils.LogErr(1000) }
func sendPolicy(conn net.Conn) { defer conn.Close() str := "<cross-domain-policy><site-control permitted-cross-domain-policies=\"master-only\"/> <allow-access-from domain=\"*\" to-ports=\"9876\" /></cross-domain-policy>" // str+="\0" Utils.LogInfo("send data=%s\n", str) _, err := Utils.ReadConn(23, conn) if err != nil { Utils.LogErr(err) } bufk := bufio.NewWriter(conn) bufk.WriteString(str) // bufk.WriteString("\\0") bufk.Flush() }
/** 增加任务到期时间 **/ func AddExpired(readyData *Entity.ReadyData, waitData *Entity.WaitData, key string, expired uint) error { //增加到期时间,就从就绪队列中删除,并添加到wait队列中 if readyData.Isset(key) { waitData.Add(key, (*readyData)[key].Value, (*readyData)[key].Expired) readyData.Del(key) //存储数据 Store.SetData(readyData, waitData) return nil } //在wait队列中的,只更新到期时间 if waitData.Isset(key) { waitData.AddExpired(key, expired) //存储数据 Store.SetData(readyData, waitData) return nil } return Utils.LogErr(1001) }
/** 解析从telnet发送过来的命令,每次调用,解析一个参数,以" "为分割 **/ func parseCommandWithTelnet(num int, conn net.Conn) ([]byte, error) { var buf [1]byte var data []byte for { _, err := conn.Read(buf[:]) if err != nil { return nil, Utils.LogErr(err) } // Utils.LogInfo("data=%siii\n",string(buf[:])) if string(buf[:]) == " " || string(buf[:]) == "\n" { break } data = append(data, buf[:]...) num-- } return data, nil }