func logoutHandler(request *http.Request, resp http.ResponseWriter, redis *models.RedisLogger, user *models.Account, p Parameter) { redis.DelOnlineUser(p.TokenId()) if len(user.Devs) > 0 { user.RmDevice(user.Devs[0]) } writeResponse(request.RequestURI, resp, nil, nil) }
func wsPushHandler(request *http.Request, resp http.ResponseWriter, redisLogger *models.RedisLogger) { conn, err := upgrader.Upgrade(resp, request, nil) if err != nil { conn.WriteJSON(errors.NewError(errors.HttpError, err.Error())) return } defer conn.Close() r := wsAuthResp{} var auth wsAuth conn.ReadJSON(&auth) //log.Println("check token:", auth.Token) if !checkTokenValid(auth.Token) { //log.Println("check token valid") redisLogger.DelOnlineUser(auth.Token) conn.WriteJSON(r) return } uid := redisLogger.OnlineUser(auth.Token) user := &models.Account{} if find, _ := user.FindByUserid(uid); !find || user.TimeLimit < 0 { r.TimeLimit = user.TimeLimit conn.WriteJSON(r) return } //redisLogger.LogLogin(user.Id) days := user.LoginDays loginCount := user.LoginCount + 1 d := nowDate() if user.LastLogin.Unix() < d.Unix() { // check wether first time login of one day days++ if user.LastLogin.Unix() < d.Unix()-24*3600 { days = 1 } loginCount = 1 } //fmt.Println(uid, "loginCount", loginCount) user.SetLastLogin(days, loginCount, time.Now()) r.Userid = uid r.LastLog = user.LastLogin.Unix() r.LoginCount = loginCount if err := conn.WriteJSON(r); err != nil { return } if len(uid) == 0 { return } redisLogger.LogVisitor(user.Id) psc := redisLogger.PubSub(user.Id) go func(conn *websocket.Conn) { //wg.Add(1) //defer log.Println("ws thread closed") //defer wg.Done() redisLogger.SetOnline(user.Id, user.Actor, true, 0) start := time.Now() defer psc.Close() for { event := &models.Event{} err := conn.ReadJSON(event) if err != nil { //log.Println(err) dur := int64(time.Since(start) / time.Second) redisLogger.SetOnline(user.Id, user.Actor, false, dur) user.UpdateStat(models.StatOnlineTime, dur) return } //log.Println("recv msg:", event.Type) switch event.Type { case models.EventMsg: m := &models.Message{ From: event.Data.From, To: event.Data.To, Body: event.Data.Body, Time: time.Now(), } if event.Data.Type == models.EventChat || event.Data.Type == models.EventGChat { m.Type = event.Data.Type m.Save() event.Data.Id = m.Id.Hex() event.Time = m.Time.Unix() redisLogger.PubMsg(m.Type, m.To, event.Bytes()) } case models.EventStatus: //fmt.Println(user.Id, event.Data.Body) switch event.Data.Type { case "loc": var lat, lng float64 var locaddr string for _, body := range event.Data.Body { switch body.Type { case "latlng": //log.Println("latlng:", body.Content) loc := strings.Split(body.Content, ",") if len(loc) != 2 { break } lat, _ = strconv.ParseFloat(loc[0], 64) lng, _ = strconv.ParseFloat(loc[1], 64) case "locaddr": //log.Println("locaddr:", body.Content) locaddr = body.Content } } user.UpdateLocation(models.Location{Lat: lat, Lng: lng}, locaddr) case "device": for _, body := range event.Data.Body { switch body.Type { case "token": token := body.Content //log.Println("device token:", token) user.AddDevice(token) } } } default: log.Println("unhandled message type:", event.Type) } } }(conn) for { switch v := psc.Receive().(type) { case redis.Message: //log.Printf("%s: message: %s\n", v.Channel, v.Data) event := &models.Event{} if err := json.Unmarshal(v.Data, event); err != nil { log.Println("parse push message error:", err) continue } // subscribe group if event.Data.Type == models.EventSub && event.Data.From == user.Id { if err := redisLogger.Subscribe(psc, event.Data.To); err != nil { log.Println(err) } continue } // unsubscribe group if event.Data.Type == models.EventUnsub && event.Data.From == user.Id { if err := redisLogger.Unsubscribe(psc, event.Data.To); err != nil { log.Println(err) } continue } if err := conn.WriteMessage(websocket.TextMessage, v.Data); err != nil { log.Println(err) return } case redis.Subscription: //log.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count) case error: //log.Println(v) return } } }