func (user *User) Run() { t := cham.DTimer.NewTicker(time.Minute * 5) t2 := cham.DTimer.NewTicker(time.Second * 5) heart := protocol.HeartBeat{} lost := 0 for { select { case t := <-t.C: log.Infoln("every 5 Minute check start, openid:", user.Openid, " time:", t) user.Save() case t2 := <-t2.C: log.Infoln("every 5 Second heart beat, time:", t2) err := user.Response(protocol.Encode(0, heart)) if err != nil { lost++ log.Infoln("user heart beat lost,openid:", user.Openid) } else { lost = 0 } // fmt.Println("---------", lost) if lost >= 5 { log.Infoln("heart beat lost more 5 time, close user service, openid:", user.Openid) user.Kill() return } } } }
//gate listen func (g *Gate) open(conf *Conf) { maxclient := conf.maxclient g.maxclient = maxclient if conf.path == "" { log.Infoln("Tcp Gate start, listen ", conf.address) listen, err := net.Listen("tcp", conf.address) if err != nil { panic("gate http open error:" + err.Error()) } go func() { defer listen.Close() for { conn, err := listen.Accept() if err != nil { continue } if maxclient != 0 && g.clinetnum >= maxclient { conn.Close() //server close socket(!net.Error) break } g.clinetnum++ session := g.nextSession() backend := newTcpBackend(session, conn) g.sessions[session] = backend // not need mutex, so not addBackend go backend.serve(g) } }() } else { log.Infoln("Websocket Gate start, listen ", conf.address) var opt = Option{wsHandler{}, false} http.HandleFunc(conf.path, func(w http.ResponseWriter, r *http.Request) { if maxclient != 0 && g.clinetnum >= maxclient { return } session := g.nextSession() ws, err := newWebsocket(w, r, &opt, session, g) if err != nil { return } g.addBackend(session, ws) g.clinetnum++ ws.Start() }) go func() { http.ListenAndServe(conf.address, nil) }() } }
func (d *debug) handle(cmds []string) string { defer func() { if err := recover(); err != nil { log.Infoln("debug cmd", cmds, " error:", err) } }() funName := strings.Title(cmds[0]) if f, ok := d.funcs[funName]; !ok { return "Invalid command, type help for command list" } else { var in []reflect.Value n := len(cmds) - 1 if n > 0 { args := cmds[1:] in = make([]reflect.Value, n) for i := 0; i < n; i++ { in[i] = reflect.ValueOf(args[i]) } } else { in = []reflect.Value{} } result := f.Call(in) return result[0].String() } }
func Start(service *cham.Service, args ...interface{}) cham.Dispatch { log.Infoln("New Service ", room.String()) room := newRoom(args[0].(Roomid)) return func(session int32, source cham.Address, ptype uint8, args ...interface{}) []interface{} { } }
//service self func Start(service *cham.Service, args ...interface{}) cham.Dispatch { log.Infoln("New Service ", service.String()) mul := new(Multicast) mul.channel = 0 mul.groups = make(map[uint32]map[cham.Address]cham.NULL, DEFAULT_GROUP_SIZE) return func(session int32, source cham.Address, ptype uint8, args ...interface{}) []interface{} { cmd := args[0].(uint8) channel := args[1].(uint32) addr := args[2].(cham.Address) result := cham.NORET switch cmd { case NEW: result = cham.Ret(mul.new(addr)) case SUB: mul.sub(addr, channel) case PUB: mul.pub(addr, channel, args[3:]...) case UNSUB: mul.unsub(addr, channel) case DEL: mul.del(channel) } return result } }
func Start(service *cham.Service, args ...interface{}) cham.Dispatch { log.Infoln("New Service ", lobby.String()) lobby := newLobby() return func(session int32, source cham.Address, ptype uint8, args ...interface{}) []interface{} { } }
func brokerStart(service *cham.Service, args ...interface{}) cham.Dispatch { log.Infoln("New Service ", service.String()) um := args[0].(*usermanager.UserManager) return func(session int32, source cham.Address, ptype uint8, args ...interface{}) []interface{} { cmd := args[0].(uint8) switch cmd { case user.DELETE_USER: openid := args[1].(string) um.Delete(openid) } return cham.NORET } }
func (d *debug) start() { listener, err := net.Listen("tcp", d.addr) if err != nil { panic("debug listen addr:" + d.addr + " ,error:" + err.Error()) } log.Infoln("debug start, listen ", d.addr) defer listener.Close() d.getfuncs() for { conn, err := listener.Accept() if err != nil { continue } go d.serve(conn) } }
func Start(service *cham.Service, args ...interface{}) cham.Dispatch { log.Infoln("New Service ", service.String()) gate := New(0, service) return func(session int32, source cham.Address, ptype uint8, args ...interface{}) []interface{} { cmd := args[0].(uint8) result := cham.NORET switch cmd { case OPEN: gate.Source = source service.RegisterProtocol(cham.PTYPE_RESPONSE, ResponseStart, gate) gate.open(args[1].(*Conf)) case KICK: gate.kick(args[1].(uint32)) } return result } }
func Start(service *cham.Service, args ...interface{}) cham.Dispatch { log.Infoln("New Service ", service.String()) openid, session := args[0].(string), args[1].(uint32) user, err := newUser(service, &model.UserModel{Openid: openid}, session) if err != nil { log.Errorln("Service ", service.String(), "init error,", err.Error()) service.Stop() } return func(session int32, source cham.Address, ptype uint8, args ...interface{}) []interface{} { cmd := args[0].(uint8) switch cmd { case CHANGE_SESSION: user.session = args[1].(uint32) } return cham.NORET } }
func (um *UserManager) Add(request *protocol.Login, session uint32) { openid := request.Openid um.RLock() if us, ok := um.users[openid]; ok { um.RUnlock() us.NotifySelf(cham.PTYPE_GO, user.CHANGE_SESSION, session) return } um.RUnlock() log.Infoln("new user,openid:", openid) us := cham.NewService(fmt.Sprintf("user-%s", openid), user.Start, 1, openid, session) if us == nil { log.Errorln("new user failed, openid:", openid) return } um.Lock() um.users[openid] = us um.Unlock() }