// auth connection func connAuth(s *nc.SocketServer, conn net.Conn, line string) error { if strings.HasPrefix(line, "AUTH:") { arr := strings.Split(line[5:], "#") // AUTH:API_ID#SECRET#VERSION if len(arr) == 3 { var af nc.AuthFunc = func() (int, error) { merchantId := dps.MerchantService.GetMerchantIdByApiId(arr[0]) apiInfo := dps.MerchantService.GetApiInfo(merchantId) if apiInfo != nil && apiInfo.ApiSecret == arr[1] { if apiInfo.Enabled == 0 { return merchantId, errors.New("api has exipres") } } return merchantId, nil } if err := s.Auth(conn, af); err != nil { return err } s.Printf("[ CLIENT] - Version = %s", arr[2]) return nil } } return errors.New("conn reject") }
// push member summary to tcp client func pushMemberSummary(s *nc.SocketServer, connList []net.Conn, memberId int) { s.Printf("[ TCP][ NOTIFY] - notify member update - %d", memberId) sm := GetMemberSummary(memberId, 0) if d, err := json.Marshal(sm); err == nil { d = append([]byte("MSUM:"), d...) for _, conn := range connList { conn.Write(append(d, '\n')) } } }
// push member summary to tcp client func pushMemberAccount(s *nc.SocketServer, connList []net.Conn, memberId int) { s.Printf("[ TCP][ NOTIFY] - notify account update - %d", memberId) sm := getMemberAccount(memberId, 0) if sm != nil { if d, err := json.Marshal(sm); err == nil { d = append([]byte("MACC:"), d...) for _, conn := range connList { conn.Write(append(d, '\n')) } } } }
func MemberSummaryNotifyJob(s *nc.SocketServer) { conn := core.GetRedisConn() defer conn.Close() for { values, err := redis.Values(conn.Do("BLPOP", variable.KvMemberUpdateTcpNotifyQueue, 0)) if err == nil { id, err := strconv.Atoi(string(values[1].([]byte))) if err == nil { connList := s.GetConnections(id) if len(connList) > 0 { go pushMemberSummary(s, connList, id) } } } } }
// Handle command of client sending. func handleCommand(s *nc.SocketServer, ci *nc.Client, cmd string) ([]byte, error) { if time.Now().Sub(ci.LatestConnectTime) > disconnectDuration { //主动关闭没有活动的连接 //s.Print("--disconnect ---",ci.Addr.String()) ci.Conn.Close() return nil, nil } if !strings.HasPrefix(cmd, "PING") { s.Printf("[ CLIENT][ MESSAGE] - send by %d ; %s", ci.Source, cmd) ci.LatestConnectTime = time.Now() } i := strings.Index(cmd, ":") if i != -1 { plan := cmd[i+1:] if v, ok := handlers[cmd[:i]]; ok { return v(ci, plan) } } return nil, errors.New("unknown command:" + cmd) }
// member auth,command like 'MAUTH:jarrysix#3234234242342342' func memberAuth(s *nc.SocketServer, id *nc.Client, param string) ([]byte, error) { var err error arr := strings.Split(param, "#") if len(arr) == 2 { f := func() (int, error) { memberId, _ := strconv.Atoi(arr[0]) authOk := util.CompareMemberApiToken(gof.CurrentApp.Storage(), memberId, arr[1]) if !authOk { return memberId, errors.New("auth fail") } return memberId, nil } if err = s.UAuth(id.Conn, f); err == nil { //验证成功 return []byte("ok"), nil } } return nil, err }
func NewServe(output bool) *nc.SocketServer { var s *nc.SocketServer r := func(conn net.Conn, b []byte) ([]byte, error) { cmd := string(b) id, ok := s.GetCli(conn) if !ok { // not join,auth first! if err := connAuth(s, conn, cmd); err != nil { return nil, err } return []byte("ok"), nil } if strings.HasPrefix(cmd, "MAUTH:") { //auth member return memberAuth(s, id, cmd[6:]) } return handleCommand(s, id, cmd) } s = nc.NewSocketServer(r) s.ReadDeadLine = defaultReadDeadLine if !output { s.OutputOff() } return s }