Merge branch 'master' of git.kingsome.cn:server_common/f5

This commit is contained in:
殷勇 2023-08-14 10:37:42 +08:00
commit a6a54ff7c1
25 changed files with 785 additions and 868 deletions

164
app.go
View File

@ -9,14 +9,35 @@ import (
"q5"
)
type App_ struct {
nodeId int
instanceId int
type App interface {
GetPkgName() string
NewUuid() int64
GetInstanceId() int32
GetNodeId() int32
GetZoneId() int32
HasFlag(int32) bool
AddIMMsg(uint16, q5.Args)
RegisterIMMsgHandle(uint16, func(q5.Args))
NotifyLoopCond()
NowUnix() int64
NowUnixMilli() int64
}
type UserApp interface {
GetPkgName() string
Init()
Update()
UnInit()
}
type app struct {
zoneId int32
nodeId int32
instanceId int32
terminated bool
pkgName string
flags map[int32]int32
servicing bool
contextHash map[int32]q5.XParams
contextHash map[int32]q5.Args
loopCond *sync.Cond
imTopNode *IMMsgNode
imBotNode *IMMsgNode
@ -26,69 +47,62 @@ type App_ struct {
chGoLoopWait chan int64
nowTime time.Time
nowUnixNano int64
imMsgHandlers [1024]func(int16,*q5.XParams)
imMsgHandlers [1024]func(q5.Args)
maxRunDelay int64
maxScheduleTime int64
updateFunc func ()
userApp UserApp
}
func (this *App_) Init(updateFunc func ()) {
this.updateFunc = updateFunc
func (this *app) init(userApp UserApp) {
this.userApp = userApp
this.nowTime = time.Now()
atomic.StoreInt64(&this.nowUnixNano, this.nowTime.UnixNano())
_Timer = &q5.Timer{}
_Timer.Init(
func (context interface{}) int64 {
return q5.GetTickCount()
},
func (context interface{}, isFirstAdd bool, milliSeconds int32, tick int64) int64 {
nowTime := time.Now().Unix()
todayPassedSeconds := nowTime - q5.GetDaySeconds(nowTime)
expires := (tick - todayPassedSeconds * 1000) + int64(milliSeconds)
if isFirstAdd {
if expires <= tick {
expires += 1000 * 3600 * 24
}
}
return expires
},
nil,
1000 * 60,
5000)
_SysLog = new(SysLog_)
_SysLog.Init()
_TgLog = new(TGLog_)
_TgLog.Init()
flag.IntVar(&this.nodeId, "n", 0, "node id")
flag.IntVar(&this.instanceId, "i", 0, "instance id")
_timer = &Timer{}
_timer.init()
_sysLog = new(SysLog_)
_sysLog.init()
_tgLog = new(TGLog_)
_tgLog.init()
_httpCliMgr = new(HttpCliMgr)
_httpCliMgr.init()
{
var tmpNodeId, tmpInstanceId int
flag.IntVar(&tmpNodeId, "n", 0, "node id")
flag.IntVar(&tmpInstanceId, "i", 0, "instance id")
this.nodeId = int32(tmpNodeId)
this.instanceId = int32(tmpInstanceId)
flag.Parse()
}
this.loopCond = sync.NewCond(new(sync.Mutex))
this.chGoLoopTimerExit = make(chan int)
this.chGoLoopWait = make(chan int64)
this.outputRuningLog()
SysLog().Info("node_id:%d instance_id:%d pid:%d",
GetSysLog().Info("node_id:%d instance_id:%d pid:%d",
this.nodeId,
this.instanceId,
os.Getpid())
this.installTimer()
go this.goLoopTimer()
this.userApp.Init()
}
func (this *App_) UnInit() {
func (this *app) unInit() {
this.chGoLoopTimerExit <- 1
_Timer.UnInit()
_Timer = nil
_httpCliMgr.unInit()
_timer.unInit()
_timer = nil
this.userApp.UnInit()
}
func (this *App_) Run() {
func (this *app) run() {
for !this.terminated {
this.nowTime = time.Now()
atomic.StoreInt64(&this.nowUnixNano, this.nowTime.UnixNano())
beginTick := q5.GetTickCount()
_Timer.Update()
_timer.update()
this.dispatchIMMsg()
this.updateFunc()
this.userApp.Update()
this.schedule()
endTick := q5.GetTickCount()
@ -98,32 +112,32 @@ func (this *App_) Run() {
}
}
func (this *App_) NewUuid() int64 {
func (this *app) NewUuid() int64 {
return 0
}
func (this *App_) GetInstanceId() uint32 {
return uint32(this.instanceId)
func (this *app) GetInstanceId() int32 {
return this.instanceId
}
func (this *App_) GetNodeId() uint32 {
return uint32(this.nodeId)
func (this *app) GetNodeId() int32 {
return this.nodeId
}
func (this *App_) GetPkgName() string {
return this.pkgName
func (this *app) GetZoneId() int32 {
return this.nodeId
}
func (this *App_) SetPkgName(pkgName string) {
this.pkgName = pkgName
func (this *app) GetPkgName() string {
return this.userApp.GetPkgName()
}
func (this *App_) HasFlag(flag int32) bool {
func (this *app) HasFlag(flag int32) bool {
_, ok := this.flags[flag]
return ok
}
func (this *App_) AddIMMsg(msgId int16, params *q5.XParams) {
func (this *app) AddIMMsg(msgId uint16, params q5.Args) {
p := new(IMMsgNode)
p.msgId = msgId
p.params = params
@ -141,11 +155,11 @@ func (this *App_) AddIMMsg(msgId int16, params *q5.XParams) {
this.loopCond.Broadcast()
}
func (this *App_) RegisterIMMsgHandle(msgId int16, handle func(int16,*q5.XParams)) {
func (this *app) RegisterIMMsgHandle(msgId uint16, handle func(q5.Args)) {
this.imMsgHandlers[msgId] = handle
}
func (this *App_) goLoopTimer() {
func (this *app) goLoopTimer() {
var waitMs int64 = 1000 * 10
for {
select {
@ -162,36 +176,33 @@ func (this *App_) goLoopTimer() {
}
}
func (this *App_) schedule() {
this.chGoLoopWait <- Timer().GetIdleTime()
func (this *app) schedule() {
this.chGoLoopWait <- GetTimer().GetIdleTime()
this.loopCond.L.Lock()
this.loopCond.Wait()
this.loopCond.L.Unlock()
}
func (this *App_) NotifyLoopCond() {
func (this *app) NotifyLoopCond() {
this.loopCond.Broadcast()
}
func (this *App_) NowUnix() int64 {
func (this *app) NowUnix() int64 {
return this.nowUnixNano / int64(time.Second)
}
func (this *App_) NowUnixMilli() int64 {
func (this *app) NowUnixMilli() int64 {
return this.nowUnixNano / int64(time.Millisecond)
}
func (this *App_) NowUnixNano() int64 {
func (this *app) NowUnixNano() int64 {
return this.nowUnixNano
}
func (this *App_) outputRuningLog() {
for _, val := range q5.GetInitLogs() {
SysLog().Info("%s", val)
}
func (this *app) outputRuningLog() {
}
func (this *App_) dispatchIMMsg() {
func (this *app) dispatchIMMsg() {
this.imMsgMutex.Lock()
this.imWorkNode = this.imTopNode
this.imTopNode = nil
@ -202,21 +213,20 @@ func (this *App_) dispatchIMMsg() {
currNode := this.imWorkNode
this.imWorkNode = this.imWorkNode.next
if this.imMsgHandlers[currNode.msgId] != nil {
this.imMsgHandlers[currNode.msgId](currNode.msgId, currNode.params)
this.imMsgHandlers[currNode.msgId](currNode.params)
}
}
}
func (this *App_) installTimer() {
Timer().AddRepeatTimer(1000 * 60,
func (params* q5.XParams) {
},
func (params* q5.XParams) {
SysLog().Info("max_run_delay:%d max_schedule_time:%d",
App.maxRunDelay,
App.maxScheduleTime)
App.maxRunDelay = 0
App.maxScheduleTime = 0
func (this *app) installTimer() {
GetTimer().SetInterval(1000 * 60,
func (ev int32, params *q5.Args) {
if ev == q5.TIMER_EXEC_EVENT {
GetSysLog().Info("max_run_delay:%d max_schedule_time:%d",
_app.maxRunDelay,
_app.maxScheduleTime)
_app.maxRunDelay = 0
_app.maxScheduleTime = 0
}
})
}

5
constant.go Normal file
View File

@ -0,0 +1,5 @@
package f5
const (
IM_HTTP_CLI_MGR_RESPONSE = 1
)

View File

@ -49,11 +49,11 @@ func (this *Context) GetRemoteAddr() string {
return q5.GetRequestRemoteAddr(this.r)
}
func (this *Context) Request(name string) *q5.XValue {
func (this *Context) Request(name string) string {
return q5.Request(this.r, name)
}
func (this *Context) GetBody() *q5.XValue {
func (this *Context) GetBody() string {
return q5.GetPostBody(this.r)
}
@ -70,10 +70,7 @@ func (this *Context) Response(data string) {
}
func (this *Context)ResponseErr(errCode int32, errMsg string) {
respObj := q5.NewMxoObject()
respObj.SetXValue("errcode", q5.NewXInt32(errCode))
respObj.SetXValue("errmsg", q5.NewXString(errMsg))
q5.Response(this.w, respObj.ToJsonStr())
q5.ResponseErr(this.w, errCode, errMsg)
}
func (this *Context) ResponseOk() {

51
dataset.go Normal file
View File

@ -0,0 +1,51 @@
package f5
import (
"database/sql"
)
type DataSet struct {
rows *sql.Rows
columns []string
values []interface{}
}
func (this *DataSet) Next() bool {
this.GetColumns()
this.values = []interface{}{}
for i := 0 ; i < len(this.columns); i++ {
str := ""
this.values = append(this.values, &str)
}
this.rows.Scan(this.values...)
return this.rows.Next()
}
func (this *DataSet) GetColumns() []string {
if len(this.columns) <= 0 {
columns, err := this.rows.Columns()
if err == nil {
this.columns = columns
}
}
return this.columns
}
func (this *DataSet) GetByName(name string) *string {
for i := 0; i < len(this.columns); i++ {
if this.columns[i] == name {
return this.GetByIndex(int32(i))
}
}
return nil
}
func (this *DataSet) GetByIndex(index int32) *string {
return this.values[index].(*string);
}
func NewDataSet(rows *sql.Rows) *DataSet {
dataSet := new(DataSet)
dataSet.rows = rows
return dataSet
}

34
export.go Normal file
View File

@ -0,0 +1,34 @@
package f5
var _app *app
var _timer *Timer
var _sysLog *SysLog_
var _tgLog *TGLog_
var _httpCliMgr *HttpCliMgr
func GetApp() App {
return _app
}
func GetTimer() *Timer {
return _timer
}
func GetSysLog() *SysLog_ {
return _sysLog
}
func GetTgLog() *TGLog_ {
return _tgLog
}
func GetHttpCliMgr() *HttpCliMgr {
return _httpCliMgr
}
func Run(userApp UserApp) {
_app = new(app)
_app.init(userApp)
_app.run()
_app.unInit()
}

View File

@ -1,20 +0,0 @@
package f5
import "q5"
var App *App_
var _Timer *q5.Timer
var _SysLog *SysLog_
var _TgLog *TGLog_
func Timer() *q5.Timer {
return _Timer
}
func SysLog() *SysLog_ {
return _SysLog
}
func TgLog() *TGLog_ {
return _TgLog
}

2
go.mod
View File

@ -1,6 +1,6 @@
module f5
go 1.14
go 1.20
require q5 v1.0.0 // indirect

144
httpclimgr.go Normal file
View File

@ -0,0 +1,144 @@
package f5
import (
"q5"
)
/*
http的请求分为两种风格
go like: go风格回调的时候不会join主线程被回调方需要处理线程同步问题
js like: js风格回调时候会自动join主线程被回调方无需处理线程同步问题
*/
const (
GO_LIKE_REQUEST = 1
JS_LIKE_REQUEST = 2
NORMAL_CHANNEL = 1
QUICK_CHANNEL = 2
)
type HttpCliResponse interface {
GetErr() error
GetJsonData() map[string]interface{}
GetRawData() string
IsTimeOut() bool
}
type httpCliResponse struct {
err error
data map[string]interface{}
rawData string
isTimeOut bool
}
type HttpCliMgr struct {
}
func (this *HttpCliMgr) init() {
_app.RegisterIMMsgHandle(
IM_HTTP_CLI_MGR_RESPONSE,
func (args q5.Args) {
cb := args[0].(func (HttpCliResponse))
rsp := args[1].(*httpCliResponse)
cb(rsp)
})
}
func (this *HttpCliMgr) unInit() {
}
func (this *HttpCliMgr) SendGoLikeRequest(
url string, params map[string]string,
cb func (HttpCliResponse)) {
this.internalSendRequest(
GO_LIKE_REQUEST,
NORMAL_CHANNEL,
url,
params,
cb)
}
func (this *HttpCliMgr) SendJsLikeRequest(
url string, params map[string]string,
cb func (HttpCliResponse)) {
this.internalSendRequest(
JS_LIKE_REQUEST,
NORMAL_CHANNEL,
url,
params,
cb)
}
func (this *HttpCliMgr) SendQuickChannelGoLikeRequest(
url string, params map[string]string,
cb func (HttpCliResponse)) {
this.internalSendRequest(
GO_LIKE_REQUEST,
QUICK_CHANNEL,
url,
params,
cb)
}
func (this *HttpCliMgr) SendQuickChannelJsLikeRequest(
url string, params map[string]string,
cb func (HttpCliResponse)) {
this.internalSendRequest(
JS_LIKE_REQUEST,
QUICK_CHANNEL,
url,
params,
cb)
}
func (this *HttpCliMgr) internalSendRequest(
style int32, channel int32,
url string, params map[string]string,
cb func (HttpCliResponse)) {
if !(style == GO_LIKE_REQUEST || style == JS_LIKE_REQUEST) {
panic("HttpCliMgr sytel error")
}
if !(channel == NORMAL_CHANNEL || channel == QUICK_CHANNEL) {
panic("HttpCliMgr channel error")
}
doFunc := func() {
data, err := q5.HttpGet(url, params)
if cb == nil {
return
}
rsp := new(httpCliResponse)
rsp.init(data, err)
if style == GO_LIKE_REQUEST {
cb(rsp)
} else {
_app.AddIMMsg(IM_HTTP_CLI_MGR_RESPONSE, []interface{} {
cb,
rsp,
})
}
}
go doFunc()
}
func (this *httpCliResponse) init(data string, err error) {
this.err = err
this.rawData = data
}
func (this *httpCliResponse) GetErr() error {
return this.err
}
func (this *httpCliResponse) GetJsonData() map[string]interface{} {
return this.data
}
func (this *httpCliResponse) GetRawData() string {
return this.rawData
}
func (this *httpCliResponse) IsTimeOut() bool {
return this.isTimeOut
}

View File

@ -40,16 +40,14 @@ func (this *HttpServer) Init(serviceName string, logOutputTime int32) *HttpServe
func (c *Context) {
c.Response(`{"errcode":0, "errmsg":"", "healthy":1, "max_rundelay":10}`)
})
SysLog().Info("HttpServer.Init")
GetSysLog().Info("HttpServer.Init")
if logOutputTime > 0 {
Timer().AddRepeatTimer(
GetTimer().SetInterval(
logOutputTime,
func (params* q5.XParams) {
params.Sender.SetString(serviceName)
},
func (params* q5.XParams) {
SysLog().Info("%s maxHandleTime:%d totalRequestTimes:%d okTimes:%d pageNotFoundTimes:%d",
params.Sender.GetString(),
func (ev int32, params *q5.Args) {
if ev == q5.TIMER_EXEC_EVENT {
GetSysLog().Info("%s maxHandleTime:%d totalRequestTimes:%d okTimes:%d pageNotFoundTimes:%d",
serviceName,
this.maxHandleTime,
this.totalRequestTimes,
this.okTimes,
@ -57,25 +55,26 @@ func (this *HttpServer) Init(serviceName string, logOutputTime int32) *HttpServe
this.maxHandleTime = 0
this.okTimes = 0
this.pageNotFoundTimes = 0
}
})
}
return this
}
func (this *HttpServer) UnInit() {
SysLog().Info("HttpServer.UnInit")
GetSysLog().Info("HttpServer.UnInit")
}
func (this *HttpServer) Start(listen_port int32) {
atomic.AddInt64(&this.totalRequestTimes, 1)
this.installGlobalMiddleware()
SysLog().Info("HttpServer.Start listen_port:%d", listen_port)
GetSysLog().Info("HttpServer.Start listen_port:%d", listen_port)
go http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", listen_port), nil)
}
func (this *HttpServer) dispatchRequest(c *Context) {
atomic.AddInt64(&this.totalRequestTimes, 1)
handleName := c.Request("c").GetString() + "$" + c.Request("a").GetString()
handleName := c.Request("c") + "$" + c.Request("a")
handle := this.getHandle(handleName)
if handle != nil {
beginTick := q5.GetTickCount()
@ -86,7 +85,7 @@ func (this *HttpServer) dispatchRequest(c *Context) {
}
atomic.AddInt64(&this.okTimes, 1)
if err := recover(); err != nil {
SysLog().Error("handle name:%s error:%s", handleName, err)
GetSysLog().Error("handle name:%s error:%s", handleName, err)
c.Response(`{"errcode":500, "errmsg":"server internal error"}`)
}
}()

View File

@ -1 +0,0 @@
package im

View File

@ -1,14 +0,0 @@
package im
type BaseIMListener struct {
}
func (this *BaseIMListener) _IMSocketConnect(msg *IMSocketConnect) {
}
func (this *BaseIMListener) _IMSocketDisconnect(msg *IMSocketDisconnect) {
}

View File

@ -1,8 +0,0 @@
package im
type IMListener interface {
_IMSocketConnect(msg *IMSocketConnect)
_IMSocketDisconnect(msg *IMSocketDisconnect)
}

View File

@ -1,83 +0,0 @@
// Code generated by protoc-gen-go.
// source: im_msgid.proto
// DO NOT EDIT!
/*
Package im is a generated protocol buffer package.
It is generated from these files:
im_msgid.proto
im_proto.proto
It has these top-level messages:
MFTuple
IMSocketConnect
IMSocketDisconnect
*/
package im
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// 消息id定义
type IMMessageIdE int32
const (
IMMessageIdE__IMSocketConnect IMMessageIdE = 1
IMMessageIdE__IMSocketDisconnect IMMessageIdE = 2
)
var IMMessageIdE_name = map[int32]string{
1: "_IMSocketConnect",
2: "_IMSocketDisconnect",
}
var IMMessageIdE_value = map[string]int32{
"_IMSocketConnect": 1,
"_IMSocketDisconnect": 2,
}
func (x IMMessageIdE) Enum() *IMMessageIdE {
p := new(IMMessageIdE)
*p = x
return p
}
func (x IMMessageIdE) String() string {
return proto.EnumName(IMMessageIdE_name, int32(x))
}
func (x *IMMessageIdE) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(IMMessageIdE_value, data, "IMMessageIdE")
if err != nil {
return err
}
*x = IMMessageIdE(value)
return nil
}
func (IMMessageIdE) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func init() {
proto.RegisterEnum("im.IMMessageIdE", IMMessageIdE_name, IMMessageIdE_value)
}
func init() { proto.RegisterFile("im_msgid.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 96 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcb, 0xcc, 0x8d, 0xcf,
0x2d, 0x4e, 0xcf, 0x4c, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xca, 0xcc, 0xd5, 0xb2,
0xe3, 0xe2, 0xf5, 0xf4, 0xf5, 0x4d, 0x2d, 0x2e, 0x4e, 0x4c, 0x4f, 0xf5, 0x4c, 0x89, 0x4f, 0x15,
0x12, 0xe1, 0x12, 0x88, 0xf7, 0xf4, 0x0d, 0xce, 0x4f, 0xce, 0x4e, 0x2d, 0x71, 0xce, 0xcf, 0xcb,
0x4b, 0x4d, 0x2e, 0x11, 0x60, 0x14, 0x12, 0xe7, 0x12, 0x86, 0x8b, 0xba, 0x64, 0x16, 0x27, 0x43,
0x25, 0x98, 0x00, 0x01, 0x00, 0x00, 0xff, 0xff, 0x15, 0xd2, 0xef, 0x38, 0x54, 0x00, 0x00, 0x00,
}

View File

@ -1,8 +0,0 @@
package im;
//id定义
enum IMMessageId_e
{
_IMSocketConnect = 1;
_IMSocketDisconnect = 2;
}

View File

@ -1,147 +0,0 @@
// Code generated by protoc-gen-go.
// source: im_proto.proto
// DO NOT EDIT!
package im
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// 常量
type ConstantE int32
const (
ConstantE_MaxIMMsgId ConstantE = 7
)
var ConstantE_name = map[int32]string{
7: "MaxIMMsgId",
}
var ConstantE_value = map[string]int32{
"MaxIMMsgId": 7,
}
func (x ConstantE) Enum() *ConstantE {
p := new(ConstantE)
*p = x
return p
}
func (x ConstantE) String() string {
return proto.EnumName(ConstantE_name, int32(x))
}
func (x *ConstantE) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(ConstantE_value, data, "ConstantE")
if err != nil {
return err
}
*x = ConstantE(value)
return nil
}
func (ConstantE) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
type MFTuple struct {
Values []string `protobuf:"bytes,1,rep,name=values" json:"values,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *MFTuple) Reset() { *m = MFTuple{} }
func (m *MFTuple) String() string { return proto.CompactTextString(m) }
func (*MFTuple) ProtoMessage() {}
func (*MFTuple) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
func (m *MFTuple) GetValues() []string {
if m != nil {
return m.Values
}
return nil
}
type IMSocketConnect struct {
IsWebsocket *bool `protobuf:"varint,1,opt,name=is_websocket" json:"is_websocket,omitempty"`
Host *string `protobuf:"bytes,2,opt,name=host" json:"host,omitempty"`
Url *string `protobuf:"bytes,3,opt,name=url" json:"url,omitempty"`
QueryStr *string `protobuf:"bytes,4,opt,name=query_str" json:"query_str,omitempty"`
Tuples []*MFTuple `protobuf:"bytes,5,rep,name=tuples" json:"tuples,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *IMSocketConnect) Reset() { *m = IMSocketConnect{} }
func (m *IMSocketConnect) String() string { return proto.CompactTextString(m) }
func (*IMSocketConnect) ProtoMessage() {}
func (*IMSocketConnect) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} }
func (m *IMSocketConnect) GetIsWebsocket() bool {
if m != nil && m.IsWebsocket != nil {
return *m.IsWebsocket
}
return false
}
func (m *IMSocketConnect) GetHost() string {
if m != nil && m.Host != nil {
return *m.Host
}
return ""
}
func (m *IMSocketConnect) GetUrl() string {
if m != nil && m.Url != nil {
return *m.Url
}
return ""
}
func (m *IMSocketConnect) GetQueryStr() string {
if m != nil && m.QueryStr != nil {
return *m.QueryStr
}
return ""
}
func (m *IMSocketConnect) GetTuples() []*MFTuple {
if m != nil {
return m.Tuples
}
return nil
}
type IMSocketDisconnect struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *IMSocketDisconnect) Reset() { *m = IMSocketDisconnect{} }
func (m *IMSocketDisconnect) String() string { return proto.CompactTextString(m) }
func (*IMSocketDisconnect) ProtoMessage() {}
func (*IMSocketDisconnect) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} }
func init() {
proto.RegisterType((*MFTuple)(nil), "im.MFTuple")
proto.RegisterType((*IMSocketConnect)(nil), "im.IMSocketConnect")
proto.RegisterType((*IMSocketDisconnect)(nil), "im.IMSocketDisconnect")
proto.RegisterEnum("im.ConstantE", ConstantE_name, ConstantE_value)
}
func init() { proto.RegisterFile("im_proto.proto", fileDescriptor1) }
var fileDescriptor1 = []byte{
// 204 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x34, 0x8e, 0xbd, 0x4e, 0xc3, 0x30,
0x14, 0x46, 0xe5, 0xba, 0xb4, 0xe4, 0xa6, 0x2a, 0x60, 0x75, 0x30, 0x82, 0xc1, 0xca, 0x64, 0x31,
0x64, 0xe0, 0x15, 0x8a, 0x90, 0x32, 0x78, 0x82, 0xdd, 0x0a, 0xc1, 0x02, 0x8b, 0xc4, 0x0e, 0xbe,
0xd7, 0xfc, 0xbc, 0x3d, 0x8a, 0x81, 0xe5, 0x93, 0xbe, 0xb3, 0x9c, 0x03, 0x7b, 0x3f, 0xd9, 0x39,
0x45, 0x8a, 0x6d, 0x59, 0xb1, 0xf2, 0x53, 0x73, 0x09, 0x5b, 0x73, 0xff, 0x98, 0xe7, 0xd1, 0x89,
0x3d, 0x6c, 0x3e, 0xfa, 0x31, 0x3b, 0x94, 0x4c, 0x71, 0x5d, 0x35, 0x09, 0xce, 0x3a, 0xf3, 0x10,
0x87, 0x37, 0x47, 0xc7, 0x18, 0x82, 0x1b, 0x48, 0x1c, 0x60, 0xe7, 0xd1, 0x7e, 0xba, 0x27, 0x2c,
0x58, 0x32, 0xc5, 0xf4, 0xa9, 0xd8, 0xc1, 0xfa, 0x35, 0x22, 0xc9, 0x95, 0x62, 0xba, 0x12, 0x35,
0xf0, 0x9c, 0x46, 0xc9, 0xcb, 0xb9, 0x80, 0xea, 0x3d, 0xbb, 0xf4, 0x6d, 0x91, 0x92, 0x5c, 0x17,
0x74, 0x05, 0x1b, 0x5a, 0x7c, 0x28, 0x4f, 0x14, 0xd7, 0xf5, 0x6d, 0xdd, 0xfa, 0xa9, 0xfd, 0x6b,
0x68, 0x0e, 0x20, 0xfe, 0x9d, 0x77, 0x1e, 0x87, 0x5f, 0xed, 0xcd, 0x35, 0xc0, 0x31, 0x06, 0xa4,
0x3e, 0x90, 0x5d, 0x3a, 0xc1, 0xf4, 0x5f, 0x9d, 0x31, 0xf8, 0xd2, 0x3d, 0x9f, 0x6f, 0x7f, 0x02,
0x00, 0x00, 0xff, 0xff, 0xef, 0x03, 0x9f, 0xae, 0xd7, 0x00, 0x00, 0x00,
}

View File

@ -1,26 +0,0 @@
package im;
//
enum Constant_e
{
MaxIMMsgId = 7;
}
message MFTuple
{
repeated string values = 1;
}
message IMSocketConnect
{
optional bool is_websocket = 1;
optional string host = 2;
optional string url = 3;
optional string query_str = 4;
repeated MFTuple tuples = 5;
}
message IMSocketDisconnect
{
}

View File

@ -1,18 +0,0 @@
package im
import "fmt"
type IMSender struct {
}
func (this *IMSender) SendMsg(msgid int16, msg interface{}) {
fmt.Println("IMSender.SendMsg\n")
}
func (this *IMSender) SendIMSocketConnect(msg *IMSocketConnect) {
this.SendMsg(100, msg)
}
func (this *IMSender) SendIMSocketDisconnect(msg *IMSocketDisconnect) {
this.SendMsg(100, msg)
}

View File

@ -1,316 +0,0 @@
package f5
import (
"os"
"bufio"
"strings"
"reflect"
"fmt"
"strconv"
"encoding/json"
"q5"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/jsonpb"
"google.golang.org/protobuf/reflect/protoreflect"
)
type MetaClass struct {
FileName string
Idx int
RawMeta interface{}
WrapMeta interface{}
PrimKey string
SecKey string
eleMeta reflect.Type
}
type MetaMgr struct {
metaClasses *[]MetaClass
rawList []interface{}
wrapList []interface{}
wrapIdHash []map[int64]interface{}
wrapNameHash []map[string]interface{}
}
func (this *MetaMgr) Init() {
}
func (this *MetaMgr) UnInit() {
}
func (this *MetaMgr) RegisterMetaClasses(metaClasses *[]MetaClass) {
for i := 0; i < len(*metaClasses); i++ {
metaClass := &(*metaClasses)[i]
msgType := reflect.TypeOf(metaClass.RawMeta).Elem()
msg := reflect.New(msgType)
metaClass.eleMeta = reflect.TypeOf(msg.Elem().FieldByName("Values").Interface()).Elem().Elem()
if metaClass.eleMeta == nil {
panic(fmt.Sprintf(
"registerMetaClasses error not found Values field %s",
metaClass.FileName))
}
}
this.metaClasses = metaClasses
}
func (this *MetaMgr) Load() {
this.rawList = make([]interface{}, len(*this.metaClasses))
this.wrapList = make([]interface{}, len(*this.metaClasses))
this.wrapIdHash = make([]map[int64]interface{}, len(*this.metaClasses))
this.wrapNameHash = make([]map[string]interface{}, len(*this.metaClasses))
this.loadRawMetaTable()
this.bindPrimKey()
this.firstInitMetaList()
this.secondInitMetaList()
}
func (this *MetaMgr) loadRawMetaTable() {
for _, metaClass := range *this.metaClasses {
rawMeta, _ := this.loadJson(&metaClass)
values := rawMeta.Elem().FieldByName("Values")
wrapMetaType := reflect.TypeOf(metaClass.WrapMeta)
wrapMetaList := reflect.MakeSlice(reflect.SliceOf(wrapMetaType), 0, values.Len())
for i := 0; i < values.Len(); i++ {
val := values.Index(i)
wrapMeta := reflect.New(reflect.TypeOf(wrapMetaList.Interface()).Elem().Elem())
clsName := reflect.TypeOf(val.Elem().Interface()).Name()
clsField := wrapMeta.Elem().FieldByName(clsName)
clsField.Set(val)
wrapMetaList = reflect.Append(wrapMetaList, wrapMeta)
}
this.rawList[metaClass.Idx] = rawMeta
this.wrapList[metaClass.Idx] = wrapMetaList.Interface()
this.wrapIdHash[metaClass.Idx] = map[int64]interface{}{}
this.wrapNameHash[metaClass.Idx] = map[string]interface{}{}
}
}
func (this *MetaMgr) bindPrimKey() {
bindFunc := func (metaClass *MetaClass, wrapMeta reflect.Value) {
primVal := wrapMeta.Elem().FieldByName(metaClass.PrimKey)
secVal := wrapMeta.Elem().FieldByName(metaClass.SecKey)
nameHash := this.wrapNameHash[metaClass.Idx]
idHash := this.wrapIdHash[metaClass.Idx]
if fieldVal, ok := primVal.Interface().(*string); ok {
if _, ok := nameHash[*fieldVal]; ok {
panic(fmt.Sprintf(
"bindPrimKey duplicated key error %s %s",
metaClass.FileName,
*fieldVal))
}
nameHash[*fieldVal] = wrapMeta
} else if fieldVal, ok := primVal.Interface().(*int32); ok {
if metaClass.SecKey == "" {
if _, ok := idHash[int64(*fieldVal)]; ok {
panic(fmt.Sprintf(
"bindPrimKey duplicated key error %s %s",
metaClass.FileName,
*fieldVal))
}
idHash[int64(*fieldVal)] = wrapMeta.Interface()
} else {
if subFieldVal, ok := secVal.Interface().(*int32); ok {
if _, ok := idHash[q5.MkInt64(*fieldVal, *subFieldVal)]; ok {
panic(fmt.Sprintf(
"bindPrimKey duplicated key error %s %s",
metaClass.FileName,
q5.MkInt64(*fieldVal, *subFieldVal)))
}
idHash[q5.MkInt64(*fieldVal, *subFieldVal)] = wrapMeta.Interface()
} else {
panic(fmt.Sprintf("bindPrimKey subField error %s", metaClass.FileName))
}
}
} else {
panic(fmt.Sprintf("bindPrimKey primKey error %s", metaClass.FileName))
}
}
for _, metaClass := range *this.metaClasses {
wrapMetaList := reflect.ValueOf(this.wrapList[metaClass.Idx])
for i := 0; i < wrapMetaList.Len(); i++ {
wrapMeta := wrapMetaList.Index(i)
if metaClass.PrimKey == "" {
this.wrapIdHash[metaClass.Idx][int64(i + 1)] = wrapMeta.Interface()
} else {
bindFunc(&metaClass, wrapMeta)
}
}
}
}
func (this *MetaMgr) loadJson(metaClass *MetaClass) (reflect.Value, error) {
if f, err := os.Open(metaClass.FileName); err == nil {
data, _ := bufio.NewReader(f).ReadString(0)
switch q5.JsonStrType(data) {
case q5.JSON_ARRAY:
break
case q5.JSON_OBJECT:
data = "[" + data + "]"
default:
panic(fmt.Sprintf("error json format %s", metaClass.FileName))
}
data = this.adjustJsonForamt(metaClass, data)
data = "{\"values\":" + data + "}"
msgType := reflect.TypeOf(metaClass.RawMeta).Elem()
msg := reflect.New(msgType)
msgPb := msg.Interface().(proto.Message)
u := jsonpb.Unmarshaler{AllowUnknownFields: true}
err := u.Unmarshal(strings.NewReader(data), msgPb)
if err != nil {
panic(fmt.Sprintf(
"parse json error %s %s %s",
err,
metaClass.FileName,
msgType.Name()))
}
return msg, err
} else {
panic(fmt.Sprintf("open metafile error %s %s", metaClass.FileName, err))
}
}
func (this *MetaMgr) GetMetaById(idx int, id int32) interface{} {
return this.GetMetaById64(idx, int64(id))
}
func (this *MetaMgr) GetMetaById64(idx int, id int64) interface{} {
if idx >=0 && idx < len(this.wrapIdHash) {
idHash := this.wrapIdHash[idx]
if v, ok := idHash[id]; ok {
return reflect.ValueOf(v).Interface()
} else {
return nil
}
}
return nil
}
func (this *MetaMgr) GetMetaByName(idx int, name string) interface{} {
if idx >=0 && idx < len(this.wrapNameHash) {
nameHash := this.wrapNameHash[idx]
if v, ok := nameHash[name]; ok {
return v
} else {
return nil
}
}
return nil
}
func (this *MetaMgr) GetMetaList(idx int) interface{} {
if idx >=0 && idx < len(this.wrapList) {
return this.wrapList[idx]
}
return nil
}
func (this *MetaMgr) adjustJsonForamt(metaClass *MetaClass, rawData string) string {
adjustFieldFunc := func(msg map[string]interface{}, key string, val interface{}, field protoreflect.FieldDescriptor) {
switch field.Kind() {
case
protoreflect.Int32Kind,
protoreflect.Sint32Kind,
protoreflect.Int64Kind,
protoreflect.Sint64Kind,
protoreflect.Uint64Kind,
protoreflect.Sfixed32Kind,
protoreflect.Fixed32Kind,
protoreflect.FloatKind,
protoreflect.Sfixed64Kind,
protoreflect.Fixed64Kind,
protoreflect.DoubleKind:
if q5.IsNumberType(val) {
} else if reflect.TypeOf(val).Kind() == reflect.String {
strVal := val.(string)
if strVal == "" {
msg[key] = 0
} else {
intVal, err := strconv.ParseInt(strVal, 10, 64)
if err == nil {
msg[key] = intVal
} else {
floatVal, err := strconv.ParseFloat(strVal, 64)
if err == nil {
msg[key] = floatVal
} else {
panic(fmt.Sprintf(
"adjustJsonFormat error %s %s %s",
metaClass.FileName,
key,
val))
}
}
}
}
case
protoreflect.BoolKind,
protoreflect.EnumKind,
protoreflect.BytesKind,
//protoreflect.MessageKind,
protoreflect.GroupKind:
panic(fmt.Sprintf(
"adjustJsonFormat error %s %s %s",
metaClass.FileName,
key,
val))
case protoreflect.MessageKind:
break
}
}
var rawJson []map[string]interface{}
err := json.Unmarshal([]byte(rawData), &rawJson)
if err != nil {
panic(fmt.Sprintf("adjustJsonFormat unmarshal error %s %s", metaClass.FileName, err))
}
msgType := proto.MessageReflect(reflect.New(metaClass.eleMeta).Interface().(proto.Message))
for i := 0; i < len(rawJson); i++ {
msg := rawJson[i]
for key, val := range msg {
field := msgType.Descriptor().Fields().ByName(protoreflect.Name(key))
if field != nil {
adjustFieldFunc(msg, key, val, field)
}
}
}
newData, err := json.Marshal(rawJson)
//fmt.Println("rawData ", string(rawData))
//fmt.Println("newData ", string(newData))
if err != nil {
panic(fmt.Sprintf("adjustJsonFormat marshal error %s %s", metaClass.FileName, err))
}
return string(newData)
}
func (this *MetaMgr) firstInitMetaList() {
for i := 0; i < len(this.wrapList); i++ {
metaList := reflect.ValueOf(this.wrapList[i])
for ii := 0; ii < metaList.Len(); ii++ {
meta := metaList.Index(ii)
initFunc := meta.MethodByName("Init")
if initFunc.IsValid() {
initFunc.Call(nil)
}
}
}
}
func (this *MetaMgr) secondInitMetaList() {
for i := 0; i < len(this.wrapList); i++ {
metaList := reflect.ValueOf(this.wrapList[i])
for i := 0; i < metaList.Len(); i++ {
meta := metaList.Index(i)
init2Func := meta.MethodByName("Init2")
if init2Func.IsValid() {
init2Func.Call(nil)
}
}
}
}

213
metatable.go Normal file
View File

@ -0,0 +1,213 @@
package f5
import (
"reflect"
"q5"
"os"
"bufio"
"fmt"
"encoding/json"
)
type MetaTable interface {
IsNoLoad() bool
Load()
PreInit1()
ElementsInit(int)
PostInit1()
}
type LoadFromKeyValue interface {
LoadFromKv(map[string]interface{})
}
type RawMetaTable[T any] struct {
FileName string
PrimKey string
NoLoad bool
rawList []*T
}
type IdMetaTable[T any] struct {
RawMetaTable[T]
idHash map[int64]*T
}
type NameMetaTable[T any] struct {
RawMetaTable[T]
nameHash map[string]*T
}
func (this *RawMetaTable[T]) Traverse(cb func (*T) bool) {
for _, val := range this.rawList {
if !cb(val) {
break
}
}
}
func (this *RawMetaTable[T]) IsNoLoad() bool {
return this.NoLoad
}
func (this *RawMetaTable[T]) PreInit1() {
}
func (this *RawMetaTable[T]) PostInit1() {
}
func (this *RawMetaTable[T]) ElementsInit(round int) {
type RoundInit1 interface {
Init1()
}
type RoundInit2 interface {
Init2()
}
type RoundInit3 interface {
Init3()
}
this.Traverse(func (obj *T) bool {
var x interface{} = obj
switch round {
case 0:
if init, ok := x.(RoundInit1); ok {
init.Init1()
}
case 1:
if init, ok := x.(RoundInit2); ok {
init.Init2()
}
case 2:
if init, ok := x.(RoundInit3); ok {
init.Init3()
}
}
return true
})
}
func (this *IdMetaTable[T]) GetById(id int64) *T {
if v, ok := this.idHash[id]; ok {
return v
} else {
return nil
}
}
func (this *RawMetaTable[T]) Load() {
if this.NoLoad {
return
}
if f, err := os.Open(this.FileName); err == nil {
jsonStr, _ := bufio.NewReader(f).ReadString(0)
switch q5.JsonStrType(jsonStr) {
case q5.JSON_ARRAY:
break
case q5.JSON_OBJECT:
jsonStr = "[" + jsonStr + "]"
default:
panic(fmt.Sprintf("error json format %s", this.FileName))
}
var rows []map[string]interface{}
json.Unmarshal([]byte(jsonStr), &rows)
for _, row := range rows {
var obj = new(T)
var x interface{} = obj
if loader, ok := x.(LoadFromKeyValue); ok {
loader.LoadFromKv(row)
}
this.rawList = append(this.rawList, obj)
}
} else {
panic(fmt.Sprintf("load metafile error %s %s", this.FileName, err))
}
}
func (this *IdMetaTable[T]) Load() {
this.RawMetaTable.Load()
this.idHash = make(map[int64]*T)
i := int64(0)
getFuncName := "Get" + q5.ConvertUpperCamelCase(this.PrimKey)
this.Traverse(func (obj *T) bool {
if this.PrimKey == "" {
this.idHash[i] = obj
} else {
in := []reflect.Value{}
method := reflect.ValueOf(obj).MethodByName(getFuncName)
out := method.Call(in)
if key, err := q5.ToInt64Ex(out[0].Interface()); err == nil {
this.idHash[key] = obj
} else {
panic("IdMetaTable load PrimKey error")
}
}
i++
return true
})
}
func (this *NameMetaTable[T]) GetByName(name string) *T {
if v, ok := this.nameHash[name]; ok {
return v
} else {
return nil
}
}
func (this *NameMetaTable[T]) Load() {
this.RawMetaTable.Load()
this.nameHash = make(map[string]*T)
i := int64(0)
getFuncName := "Get" + q5.ConvertUpperCamelCase(this.PrimKey)
this.Traverse(func (obj *T) bool {
in := []reflect.Value{}
method := reflect.ValueOf(obj).MethodByName(getFuncName)
out := method.Call(in)
if key, err := q5.ToStringEx(out[0].Interface()); err == nil {
this.nameHash[key] = obj
} else {
panic("NameMetaTable load PrimKey error")
}
i++
return true
})
}
func ReadMetaTableField[T string | int | int32 | int64 | float32 | float64](
fieldPtr *T, fieldName string, flags *uint64, flagIdx uint64,
kv map[string]interface{}) {
if val, ok := kv[fieldName]; ok {
if !q5.DuckToSimple(val, fieldPtr) {
panic("ReadMetaTableField error")
}
*flags |= uint64(1) << flagIdx
}
}
func LoadMetaTable(table interface{}) {
ele := reflect.ValueOf(table).Elem()
for i := 0; i < ele.NumField(); i++ {
var tbl MetaTable = ele.Field(i).Interface().(MetaTable)
if !tbl.IsNoLoad() {
tbl.PreInit1()
}
}
for i := 0; i < ele.NumField(); i++ {
var tbl MetaTable = ele.Field(i).Interface().(MetaTable)
if !tbl.IsNoLoad() {
tbl.Load()
}
}
for i := 0; i < 3; i++ {
for ii := 0; ii < ele.NumField(); ii++ {
var tbl MetaTable = ele.Field(ii).Interface().(MetaTable)
tbl.ElementsInit(i)
}
}
for i := 0; i < ele.NumField(); i++ {
var tbl MetaTable = ele.Field(i).Interface().(MetaTable)
if !tbl.IsNoLoad() {
tbl.PostInit1()
}
}
}

89
prototils.go Normal file
View File

@ -0,0 +1,89 @@
package f5
import (
"q5"
"net"
)
type MsgHdr struct {
MsgId uint16
SeqId uint32
SocketHandle uint16
IpSaddr uint32
Conn net.Conn
Data []byte
Msg interface{}
Entry q5.ListHead
}
type NetMsg interface {
GetNetMsgId() uint16
}
/*
struct WSProxyPackHead_C
{
unsigned short packlen;
unsigned short msgid;
unsigned int seqid;
unsigned short magic_code;
unsigned short socket_handle;
unsigned long ip_saddr;
};
*/
type WSProxyPackHead_C struct {
PackLen uint16
MsgId uint16
SeqId uint32
MagicCode uint16
SocketHandle uint16
IpSaddr uint64
}
/*
struct WSProxyPackHead_S
{
unsigned short packlen;
unsigned short msgid;
unsigned int seqid;
unsigned short magic_code;
unsigned short rpc_error_code;
unsigned short socket_handle;
unsigned short ext_len;
};
*/
type WSProxyPackHead_S struct {
PackLen uint16
MsgId uint16
SeqId uint32
MagicCode uint16
RpcErrCode uint16
SocketHandle uint16
ExtLen uint16
}
func (this *WSProxyPackHead_C) Read(data []byte, offset int) {
this.PackLen = q5.MkUInt16(data[offset + 0], data[offset + 1])
this.MsgId = q5.MkUInt16(data[offset + 2], data[offset + 3])
this.SeqId = q5.MkUInt32(data[offset + 4], data[offset + 5],
data[offset + 6], data[offset + 7])
this.MagicCode = q5.MkUInt16(data[offset + 8], data[offset + 9])
this.SocketHandle = q5.MkUInt16(data[offset + 10], data[offset + 11])
}
func (this *WSProxyPackHead_S) Write(data []byte, offset int) {
data[offset + 0] = byte(this.PackLen & 0xFF)
data[offset + 1] = byte(this.PackLen >> 8)
data[offset + 2] = byte(this.MsgId & 0xFF)
data[offset + 3] = byte(this.MsgId >> 8)
data[offset + 8] = byte('K')
data[offset + 9] = byte('S')
data[offset + 12] = byte(this.SocketHandle & 0xFF)
data[offset + 13] = byte(this.SocketHandle >> 8)
}

View File

@ -22,6 +22,7 @@ const SYS_LOG_ROOT = "/data/logs/%s/logs/"
const SYS_LOG_FILENAME = "log_%d_%s.log"
type LogMsgNode struct {
category int32
logMsg string
next *LogMsgNode
}
@ -34,12 +35,12 @@ type SysLog_ struct {
chGoSaveExit chan int
}
func (this *SysLog_) Init() {
func (this *SysLog_) init() {
this.chGoSaveExit = make(chan int)
go this.goSaveToFile()
}
func (this *SysLog_) UnInit() {
func (this *SysLog_) unInit() {
this.chGoSaveExit <- 1
}
@ -47,57 +48,59 @@ func (this *SysLog_) Emergency(format string, args ...interface{}) {
if this.logLevel > LOG_EMERGENCY {
return
}
this.addLog("[EMERGENCY]", format, args...)
this.addLog(LOG_EMERGENCY, "[EMERGENCY]", format, args...)
}
func (this *SysLog_) Alert(format string, args ...interface{}) {
if this.logLevel > LOG_ALERT {
return
}
this.addLog("[ALERT]", format, args...)
this.addLog(LOG_ALERT, "[ALERT]", format, args...)
}
func (this *SysLog_) Error(format string, args ...interface{}) {
if this.logLevel > LOG_ERROR {
return
}
this.addLog("[ERROR]", format, args...)
this.addLog(LOG_ERROR, "[ERROR]", format, args...)
}
func (this *SysLog_) Warning(format string, args ...interface{}) {
if this.logLevel > LOG_WARNING {
return
}
this.addLog("[WARNING]", format, args...)
this.addLog(LOG_WARNING, "[WARNING]", format, args...)
}
func (this *SysLog_) Notice(format string, args ...interface{}) {
if this.logLevel > LOG_NOTICE {
return
}
this.addLog("[NOTICE]", format, args...)
this.addLog(LOG_NOTICE, "[NOTICE]", format, args...)
}
func (this *SysLog_) Info(format string, args ...interface{}) {
if this.logLevel > LOG_INFO {
return
}
this.addLog("[INFO]", format, args...)
this.addLog(LOG_INFO, "[INFO]", format, args...)
}
func (this *SysLog_) Debug(format string, args ...interface{}) {
if this.logLevel > LOG_DEBUG {
return
}
this.addLog("[DEBUG]", format, args...)
this.addLog(LOG_DEBUG, "[DEBUG]", format, args...)
}
func (this *SysLog_) addLog(category string, format string, args ...interface{}) {
func (this *SysLog_) addLog(category int32, prefixStr string,
format string, args ...interface{}) {
p := &LogMsgNode{}
p.category = category
p.logMsg = time.Now().Format("2006-01-02 15:04:05") +
category + " " +
prefixStr + " " +
fmt.Sprintf(format, args...) + "\n"
if q5.Debug() {
if category == LOG_INFO {
fmt.Print(p.logMsg)
}
this.msgMutex.Lock()
@ -125,7 +128,7 @@ func (this *SysLog_) goSaveToFile() {
this.botNode = nil
this.msgMutex.Unlock()
if workNode != nil {
logDir := fmt.Sprintf(SYS_LOG_ROOT, App.GetPkgName())
logDir := fmt.Sprintf(SYS_LOG_ROOT, GetApp().GetPkgName())
fileName := fmt.Sprintf(TGLOG_FILENAME, os.Getpid(), time.Now().Format("20060102"))
q5.ForceCreateDir(logDir)
if f, err := os.OpenFile(logDir + fileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666); err == nil {

View File

@ -2,8 +2,8 @@ package f5
import (
"os"
"strings"
"q5"
//"strings"
//"q5"
)
const (
@ -26,19 +26,7 @@ func IsDevEnv() bool {
return serverEnv == DEV_ENV
}
func IsValidSessionId(accountId string, sessionId string, key string) bool {
tmpStrings := strings.Split(sessionId, "_")
if len(tmpStrings) < 4 {
return false
}
sessionCreateTime := new(q5.XValue).SetString(tmpStrings[0]).GetString()
registerTime := new(q5.XValue).SetString(tmpStrings[1]).GetString()
md5Str := new(q5.XValue).SetString(tmpStrings[2]).GetString()
//SysLog().Debug("%s", accountId + key + registerTime + sessionCreateTime)
//SysLog().Debug("md51=%s md52=%s", q5.Md5Str(accountId + key + registerTime + sessionCreateTime), md5Str)
return q5.Md5Str(accountId + key + registerTime + sessionCreateTime) == md5Str
}
/*
func ExtractRegisterTimeFromSessionId(sessionId string) int64 {
tmpStrings := strings.Split(sessionId, "_")
if len(tmpStrings) < 4 {
@ -70,6 +58,12 @@ func ExtractOpenIdFromAccountId(accountId string) string {
}
return strings.Join(tmpStrings[2:], "_")
}
*/
func New[T any](cb func(*T)) *T {
obj := new(T)
cb(obj)
return obj
}
func init() {
switch os.Getenv("SERVER_ENV") {

View File

@ -1,10 +1,10 @@
package f5
import "os"
import "fmt"
//import "os"
//import "fmt"
import "sync"
import "time"
import "q5"
//import "time"
//import "q5"
const TGLOG_ROOT = "/data/logs/%s/upload/"
const POLY_TGLOG_ROOT = "/data/logs/%s/%d/upload/"
@ -24,12 +24,12 @@ type TGLog_ struct {
chGoSaveExit chan int
}
func (this *TGLog_) Init() {
func (this *TGLog_) init() {
this.chGoSaveExit = make(chan int)
go this.goSaveToFile()
//go this.goSaveToFile()
}
func (this *TGLog_) UnInit() {
func (this *TGLog_) unInit() {
this.chGoSaveExit <- 1
}
@ -37,6 +37,7 @@ func (this *TGLog_) SetPolyLog(isPolyLog bool) {
this.isPolyLog = isPolyLog
}
/*
func (this *TGLog_) AddTrackLog(
gameId int32,
accountId string,
@ -75,8 +76,9 @@ func (this *TGLog_) AddTrackLogEx(
this.topNode = p
this.botNode = p
}
}
//}
*/
/*
func (this *TGLog_) goSaveToFile() {
var workNode *TGLogMsgNode
for {
@ -119,3 +121,5 @@ func (this *TGLog_) getLogFile(gameId int32) *os.File {
return nil
}
}
*/

99
timer.go Normal file
View File

@ -0,0 +1,99 @@
package f5
import (
"q5"
)
type TimerWp struct {
*q5.XTimerWp
}
type TimerAttacher struct {
*q5.XTimerAttacher
}
type Timer struct {
timer *q5.XTimer
}
func (this *Timer) init() {
this.timer = new(q5.XTimer)
this.timer.Init(
func (context interface{}) int64 {
return q5.GetTickCount()
},
nil,
1000 * 60,
5000)
}
func (this *Timer) update() {
this.timer.Update()
}
func (this *Timer) unInit() {
this.timer.UnInit()
this.timer = nil
}
func (this *Timer) NewTimerAttacher() *TimerAttacher {
ac := TimerAttacher{}
ac.XTimerAttacher = this.timer.NewTimerAttacher()
return &ac
}
func (this *Timer) SetTimeout(expireTime int32, cb q5.TimerCb) {
this.timer.SetTimeout(expireTime, cb)
}
func (this *Timer) SetTimeoutEx(expireTime int32, cb q5.TimerCb, ac *TimerAttacher) {
this.timer.SetTimeoutEx(expireTime, cb, ac.XTimerAttacher)
}
func (this *Timer) SetTimeoutWp(expireTime int32, cb q5.TimerCb) *TimerWp {
wp := TimerWp{}
wp.XTimerWp = this.timer.SetTimeoutWp(expireTime, cb)
return &wp
}
func (this *Timer) SetTimeoutExWp(expireTime int32, cb q5.TimerCb, ac *TimerAttacher) *TimerWp {
wp := TimerWp{}
wp.XTimerWp = this.timer.SetTimeoutExWp(expireTime, cb, ac.XTimerAttacher)
return &wp
}
func (this *Timer) SetInterval(expireTime int32, cb q5.TimerCb) {
this.timer.SetInterval(expireTime, cb)
}
func (this *Timer) SetIntervalEx(expireTime int32, cb q5.TimerCb, ac *TimerAttacher) {
this.timer.SetIntervalEx(expireTime, cb, ac.XTimerAttacher)
}
func (this *Timer) SetIntervalWp(expireTime int32, cb q5.TimerCb) *TimerWp {
wp := TimerWp{}
wp.XTimerWp = this.timer.SetIntervalWp(expireTime, cb)
return &wp
}
func (this *Timer) SetIntervalExWp(expireTime int32, cb q5.TimerCb, ac *TimerAttacher) *TimerWp {
wp := TimerWp{}
wp.XTimerWp = this.timer.SetIntervalExWp(expireTime, cb, ac.XTimerAttacher)
return &wp
}
func (this *Timer) GetIdleTime() int64 {
return this.timer.GetIdleTime()
}
func (this *Timer) ModifyTimer(timerWp *TimerWp, expireTime int32) {
this.timer.ModifyTimer(timerWp.XTimerWp, expireTime)
}
func (this *Timer) Delete(timerWp *TimerWp) {
this.timer.Delete(timerWp.XTimerWp)
}
func (this *Timer) GetRemainTime(timerWp *TimerWp) int64 {
return this.timer.GetRemainTime(timerWp.XTimerWp)
}

View File

@ -2,7 +2,6 @@ package f5
import (
"q5"
"net"
)
const (
@ -16,8 +15,8 @@ type MsgNode struct {
}
type IMMsgNode struct {
msgId int16
params *q5.XParams
msgId uint16
params q5.Args
next *IMMsgNode
}
@ -28,86 +27,3 @@ type middleware struct {
handlerFunc HandlerFunc
entry q5.ListHead
}
type MsgHdr struct {
MsgId uint16
SeqId uint32
SocketHandle uint16
IpSaddr uint32
Conn net.Conn
Data []byte
Msg interface{}
Entry q5.ListHead
}
type NetMsg interface {
GetNetMsgId() uint16
}
/*
struct WSProxyPackHead_C
{
unsigned short packlen;
unsigned short msgid;
unsigned int seqid;
unsigned short magic_code;
unsigned short socket_handle;
unsigned long ip_saddr;
};
*/
type WSProxyPackHead_C struct {
PackLen uint16
MsgId uint16
SeqId uint32
MagicCode uint16
SocketHandle uint16
IpSaddr uint64
}
/*
struct WSProxyPackHead_S
{
unsigned short packlen;
unsigned short msgid;
unsigned int seqid;
unsigned short magic_code;
unsigned short rpc_error_code;
unsigned short socket_handle;
unsigned short ext_len;
};
*/
type WSProxyPackHead_S struct {
PackLen uint16
MsgId uint16
SeqId uint32
MagicCode uint16
RpcErrCode uint16
SocketHandle uint16
ExtLen uint16
}
func (this *WSProxyPackHead_C) Read(data []byte, offset int) {
this.PackLen = q5.MkUInt16(data[offset + 0], data[offset + 1])
this.MsgId = q5.MkUInt16(data[offset + 2], data[offset + 3])
this.SeqId = q5.MkUInt32(data[offset + 4], data[offset + 5],
data[offset + 6], data[offset + 7])
this.MagicCode = q5.MkUInt16(data[offset + 8], data[offset + 9])
this.SocketHandle = q5.MkUInt16(data[offset + 10], data[offset + 11])
}
func (this *WSProxyPackHead_S) Write(data []byte, offset int) {
data[offset + 0] = byte(this.PackLen & 0xFF)
data[offset + 1] = byte(this.PackLen >> 8)
data[offset + 2] = byte(this.MsgId & 0xFF)
data[offset + 3] = byte(this.MsgId >> 8)
data[offset + 8] = byte('K')
data[offset + 9] = byte('S')
data[offset + 12] = byte(this.SocketHandle & 0xFF)
data[offset + 13] = byte(this.SocketHandle >> 8)
}