func (client *TCPClient) init() { client.Lock() defer client.Unlock() if client.ConnNum <= 0 { client.ConnNum = 1 log.Release("invalid ConnNum, reset to %v", client.ConnNum) } if client.ConnectInterval <= 0 { client.ConnectInterval = 3 * time.Second log.Release("invalid ConnectInterval, reset to %v", client.ConnectInterval) } if client.PendingWriteNum <= 0 { client.PendingWriteNum = 100 log.Release("invalid PendingWriteNum, reset to %v", client.PendingWriteNum) } if client.NewAgent == nil { log.Fatal("NewAgent must not be nil") } if client.conns != nil { log.Fatal("client is running") } client.conns = make(ConnSet) client.closeFlag = false // msg parser msgParser := NewMsgParser() msgParser.SetMsgLen(client.LenMsgLen, client.MinMsgLen, client.MaxMsgLen) msgParser.SetByteOrder(client.LittleEndian) client.msgParser = msgParser }
func (server *TCPServer) init() { ln, err := net.Listen("tcp", server.Addr) if err != nil { log.Fatal("%v", err) } if server.MaxConnNum <= 0 { server.MaxConnNum = 100 log.Release("invalid MaxConnNum, reset to %v", server.MaxConnNum) } if server.PendingWriteNum <= 0 { server.PendingWriteNum = 100 log.Release("invalid PendingWriteNum, reset to %v", server.PendingWriteNum) } if server.NewAgent == nil { log.Fatal("NewAgent must not be nil") } server.ln = ln server.conns = make(ConnSet) // msg parser msgParser := NewMsgParser() msgParser.SetMsgLen(server.LenMsgLen, server.MinMsgLen, server.MaxMsgLen) msgParser.SetByteOrder(server.LittleEndian) server.msgParser = msgParser }
//初始化TCP服务器 func (server *TCPServer) init() { ln, err := net.Listen("tcp", server.Addr) //监听 if err != nil { log.Fatal("%v", err) } if server.MaxConnNum <= 0 { //最大连接数小于0,重置到100 server.MaxConnNum = 100 log.Release("invalid MaxConnNum, reset to %v", server.MaxConnNum) } if server.PendingWriteNum <= 0 { //发送缓冲区长度小于0,重置到100 server.PendingWriteNum = 100 log.Release("invalid PendingWriteNum, reset to %v", server.PendingWriteNum) } if server.NewAgent == nil { //创建代理函数不能为空 log.Fatal("NewAgent must not be nil") } server.ln = ln //保存监听连接器 server.conns = make(ConnSet) //创建连接集合 server.closeFlag = false //关闭标志 // msg parser msgParser := NewMsgParser() //创建消息解析器 msgParser.SetMsgLen(server.LenMsgLen, server.MinMsgLen, server.MaxMsgLen) //设置消息长度 msgParser.SetByteOrder(server.LittleEndian) //设置字节序 server.msgParser = msgParser //保存消息解析器 }
func Run(mods ...module.Module) { //...不定参数语法,参数类型都为module.Module // logger if conf.LogLevel != "" { //日志级别不为空 logger, err := log.New(conf.LogLevel, conf.LogPath) //创建一个logger if err != nil { panic(err) } log.Export(logger) //替换默认的gLogger defer logger.Close() //Run函数返回,关闭logger } log.Release("Leaf starting up") //关键日志 // module for i := 0; i < len(mods); i++ { //遍历传入的所有module module.Register(mods[i]) //注册module } module.Init() //初始化模块,并执行各个模块(在各个不同的goroutine里) // console console.Init() //初始化控制台 // close c := make(chan os.Signal, 1) //新建一个管道用于接收系统Signal signal.Notify(c, os.Interrupt, os.Kill) //监听SIGINT和SIGKILL信号(linux下叫这个名字) sig := <-c //读信号,没有信号时会阻塞goroutine log.Release("Leaf closing down (signal: %v)", sig) //关键日志 服务器关闭 console.Destroy() //销毁控制台 module.Destroy() //销毁模块 }
func Run(mods ...module.Module) { // logger if conf.LogLevel != "" { logger, err := log.New(conf.LogLevel, conf.LogPath) if err != nil { panic(err) } log.Export(logger) defer logger.Close() } log.Release("Leaf starting up") // module for i := 0; i < len(mods); i++ { module.Register(mods[i]) } module.Init() // cluster cluster.Init() // console console.Init() // close c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, os.Kill) sig := <-c log.Release("Leaf closing down (signal: %v)", sig) console.Destroy() cluster.Destroy() module.Destroy() }
func (server *WSServer) Start() { ln, err := net.Listen("tcp", server.Addr) if err != nil { log.Fatal("%v", err) } if server.MaxConnNum <= 0 { server.MaxConnNum = 100 log.Release("invalid MaxConnNum, reset to %v", server.MaxConnNum) } if server.PendingWriteNum <= 0 { server.PendingWriteNum = 100 log.Release("invalid PendingWriteNum, reset to %v", server.PendingWriteNum) } if server.MaxMsgLen <= 0 { server.MaxMsgLen = 4096 log.Release("invalid MaxMsgLen, reset to %v", server.MaxMsgLen) } if server.HTTPTimeout <= 0 { server.HTTPTimeout = 10 * time.Second log.Release("invalid HTTPTimeout, reset to %v", server.HTTPTimeout) } if server.NewAgent == nil { log.Fatal("NewAgent must not be nil") } server.ln = ln server.handler = &WSHandler{ maxConnNum: server.MaxConnNum, pendingWriteNum: server.PendingWriteNum, maxMsgLen: server.MaxMsgLen, newAgent: server.NewAgent, conns: make(WebsocketConnSet), upgrader: websocket.Upgrader{ HandshakeTimeout: server.HTTPTimeout, CheckOrigin: func(_ *http.Request) bool { return true }, }, } httpServer := &http.Server{ Addr: server.Addr, Handler: server.handler, ReadTimeout: server.HTTPTimeout, WriteTimeout: server.HTTPTimeout, MaxHeaderBytes: 1024, } go httpServer.Serve(ln) }
// goroutine safe func DialWithTimeout(url string, sessionNum int, dialTimeout time.Duration, timeout time.Duration) (*DialContext, error) { if sessionNum <= 0 { sessionNum = 100 log.Release("invalid sessionNum, reset to %v", sessionNum) } s, err := mgo.DialWithTimeout(url, dialTimeout) if err != nil { return nil, err } s.SetSyncTimeout(timeout) s.SetSocketTimeout(timeout) c := new(DialContext) // sessions c.sessions = make(SessionHeap, sessionNum) c.sessions[0] = &Session{s, 0, 0} for i := 1; i < sessionNum; i++ { c.sessions[i] = &Session{s.New(), 0, i} } heap.Init(&c.sessions) return c, nil }
func Run(mods ...module.Module) { // logger if conf.LogLevel != "" { logger, err := log.New(conf.LogLevel, conf.LogPath) if err != nil { panic(err) } log.Export(logger) defer logger.Close() } log.Release("Leaf starting up") // profile if conf.EnableProfiling { now := time.Now() filename := fmt.Sprintf("%d%02d%02d_%02d_%02d_%02d.prof", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second()) f, err := os.Create(path.Join(conf.ProfilePath, filename)) if err != nil { log.Fatal("%v", err) } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } // module for i := 0; i < len(mods); i++ { module.Register(mods[i]) } module.Init() // close c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, os.Kill) sig := <-c log.Release("Leaf closing down (signal: %v)", sig) module.Destroy() }
func (server *TCPServer) run() { server.wgLn.Add(1) defer server.wgLn.Done() var tempDelay time.Duration for { conn, err := server.ln.Accept() if err != nil { if ne, ok := err.(net.Error); ok && ne.Temporary() { if tempDelay == 0 { tempDelay = 5 * time.Millisecond } else { tempDelay *= 2 } if max := 1 * time.Second; tempDelay > max { tempDelay = max } log.Release("accept error: %v; retrying in %v", err, tempDelay) time.Sleep(tempDelay) continue } return } tempDelay = 0 server.mutexConns.Lock() if len(server.conns) >= server.MaxConnNum { server.mutexConns.Unlock() conn.Close() log.Debug("too many connections") continue } server.conns[conn] = struct{}{} server.mutexConns.Unlock() server.wgConns.Add(1) tcpConn := newTCPConn(conn, server.PendingWriteNum, server.msgParser) agent := server.NewAgent(tcpConn) go func() { agent.Run() // cleanup tcpConn.Destroy() server.mutexConns.Lock() delete(server.conns, conn) server.mutexConns.Unlock() agent.OnClose() server.wgConns.Done() }() } }
func (client *TCPClient) dial() net.Conn { for { conn, err := net.Dial("tcp", client.Addr) if err == nil || client.closeFlag { return conn } log.Release("connect to %v error: %v", client.Addr, err) time.Sleep(client.ConnectInterval) continue } }
func (client *WSClient) dial() *websocket.Conn { for { conn, _, err := client.dialer.Dial(client.Addr, nil) if err == nil || client.closeFlag { return conn } log.Release("connect to %v error: %v", client.Addr, err) time.Sleep(client.ConnectInterval) continue } }
func Example() { name := "Leaf" log.Debug("My name is %v", name) log.Release("My name is %v", name) log.Error("My name is %v", name) // log.Fatal("My name is %v", name) logger, err := log.New("release", "") if err != nil { return } defer logger.Close() logger.Debug("will not print") logger.Release("My name is %v", name) log.Export(logger) log.Debug("will not print") log.Release("My name is %v", name) }
func (client *WSClient) init() { client.Lock() defer client.Unlock() if client.ConnNum <= 0 { client.ConnNum = 1 log.Release("invalid ConnNum, reset to %v", client.ConnNum) } if client.ConnectInterval <= 0 { client.ConnectInterval = 3 * time.Second log.Release("invalid ConnectInterval, reset to %v", client.ConnectInterval) } if client.PendingWriteNum <= 0 { client.PendingWriteNum = 100 log.Release("invalid PendingWriteNum, reset to %v", client.PendingWriteNum) } if client.MaxMsgLen <= 0 { client.MaxMsgLen = 4096 log.Release("invalid MaxMsgLen, reset to %v", client.MaxMsgLen) } if client.HandshakeTimeout <= 0 { client.HandshakeTimeout = 10 * time.Second log.Release("invalid HandshakeTimeout, reset to %v", client.HandshakeTimeout) } if client.NewAgent == nil { log.Fatal("NewAgent must not be nil") } if client.conns != nil { log.Fatal("client is running") } client.conns = make(WebsocketConnSet) client.closeFlag = false client.dialer = websocket.Dialer{ HandshakeTimeout: client.HandshakeTimeout, } }
func (data *UserData) saveDB() error { //save User id := data.User.Id affected, err := model.Engine.Id(id).AllCols().Omit("Id", "AccId").Update(data.User) if err != nil { return fmt.Errorf("save db error: %v", err) } if affected != 1 { log.Error("%v", "save db no affect,may be an error") } else { log.Release("%v", "save db ok") } return nil }
// goroutine safe //连接mongodb数据库,返回拨号上下文 func Dial(url string, sessionNum int) (*DialContext, error) { if sessionNum <= 0 { //非法会话数 sessionNum = 100 //重置为100 log.Release("invalid sessionNum, reset to %v", sessionNum) } s, err := mgo.Dial(url) //连接数据库 if err != nil { return nil, err } c := new(DialContext) //创建拨号上下文 // sessions c.sessions = make(SessionHeap, sessionNum) //创建会话堆 c.sessions[0] = &Session{s, 0, 0} //保存会话,0索引 for i := 1; i < sessionNum; i++ { c.sessions[i] = &Session{s.New(), 0, i} //利用原始会话创建新的会话。1,2,3,i索引 } heap.Init(&c.sessions) //A heap must be initialized before any of the heap operations can be used return c, nil }
// goroutine safe func Dial(url string, sessionNum int) (*DialContext, error) { if sessionNum <= 0 { sessionNum = 100 log.Release("invalid sessionNum, reset to %v", sessionNum) } s, err := mgo.Dial(url) if err != nil { return nil, err } c := new(DialContext) // sessions c.sessions = make(SessionHeap, sessionNum) c.sessions[0] = &Session{s, 0, 0} for i := 1; i < sessionNum; i++ { c.sessions[i] = &Session{s.New(), 0, i} } heap.Init(&c.sessions) return c, nil }