merge all branch and change project structure

This commit is contained in:
Gordon
2021-11-10 15:24:59 +08:00
91 changed files with 3612 additions and 1225 deletions
+21 -6
View File
@@ -3,14 +3,22 @@ package config
import (
"gopkg.in/yaml.v3"
"io/ioutil"
"path/filepath"
"runtime"
)
var (
_, b, _, _ = runtime.Caller(0)
// Root folder of this project
Root = filepath.Join(filepath.Dir(b), "../../..")
)
var Config config
type config struct {
ServerIP string `yaml:"serverip"`
Api struct {
ServerIP string `yaml:"serverip"`
ServerVersion string `yaml:"serverversion"`
Api struct {
GinPort []int `yaml:"openImApiPort"`
}
Sdk struct {
@@ -110,6 +118,11 @@ type config struct {
SecretKey string `yaml:"secretKey"`
}
}
Jpns struct {
AppKey string `yaml:"appKey"`
MasterSecret string `yaml:"masterSecret"`
PushUrl string `yaml:"pushUrl"`
}
}
Manager struct {
AppManagerUid []string `yaml:"appManagerUid"`
@@ -147,14 +160,16 @@ type config struct {
}
func init() {
bytes, err := ioutil.ReadFile("config/config.yaml")
//path, _ := os.Getwd()
//bytes, err := ioutil.ReadFile(path + "/config/config.yaml")
// if we cd Open-IM-Server/src/utils and run go test
// it will panic cannot find config/config.yaml
bytes, err := ioutil.ReadFile(Root + "/config/config.yaml")
if err != nil {
panic(err)
return
}
if err = yaml.Unmarshal(bytes, &Config); err != nil {
panic(err)
return
}
}
+25 -16
View File
@@ -17,22 +17,27 @@ const (
RefuseFriendFlag = -1
//Websocket Protocol
WSGetNewestSeq = 1001
WSPullMsg = 1002
WSSendMsg = 1003
WSPushMsg = 2001
WSGetNewestSeq = 1001
WSPullMsg = 1002
WSSendMsg = 1003
WSPullMsgBySeqList = 1004
WSPushMsg = 2001
WSDataError = 3001
///ContentType
//UserRelated
Text = 101
Picture = 102
Voice = 103
Video = 104
File = 105
AtText = 106
Custom = 110
Text = 101
Picture = 102
Voice = 103
Video = 104
File = 105
AtText = 106
Custom = 110
HasReadReceipt = 112
Typing = 113
Common = 200
GroupMsg = 201
SyncSenderMsg = 108
//SysRelated
AcceptFriendApplicationTip = 201
AddFriendTip = 202
@@ -64,10 +69,14 @@ const (
)
var ContentType2PushContent = map[int64]string{
Picture: "[picture]",
Voice: "[voice]",
Video: "[video]",
File: "[file]",
Picture: "[图片]",
Voice: "[语音]",
Video: "[视频]",
File: "[文件]",
Text: "你收到了一条文本消息",
AtText: "[有人@你]",
GroupMsg: "你收到一条群聊消息",
Common: "你收到一条新消息",
}
const FriendAcceptTip = "You have successfully become friends, so start chatting"
+5
View File
@@ -39,6 +39,11 @@ func init() {
}
DB.mgoSession = mgoSession
DB.mgoSession.SetMode(mgo.Monotonic, true)
c := DB.mgoSession.DB(config.Config.Mongo.DBDatabase).C(cChat)
err = c.EnsureIndexKey("uid")
if err != nil {
panic(err)
}
// redis pool init
DB.redisPool = &redis.Pool{
+111 -13
View File
@@ -1,17 +1,20 @@
package db
import (
pbMsg "Open_IM/pkg/proto/chat"
"Open_IM/pkg/common/config"
"Open_IM/pkg/common/constant"
"Open_IM/pkg/common/log"
pbMsg "Open_IM/pkg/proto/chat"
"errors"
"github.com/golang/protobuf/proto"
"gopkg.in/mgo.v2/bson"
"strconv"
"time"
)
const cChat = "chat"
const cGroup = "group"
const singleGocMsgNum = 5000
type MsgInfo struct {
SendTime int64
@@ -28,8 +31,8 @@ type GroupMember struct {
UIDList []string
}
func (d *DataBases) GetUserChat(uid string, seqBegin, seqEnd int64) (SingleMsg []*pbMsg.MsgFormat, GroupMsg []*pbMsg.MsgFormat, MaxSeq int64, MinSeq int64, err error) {
count := 0
func (d *DataBases) GetMsgBySeqRange(uid string, seqBegin, seqEnd int64) (SingleMsg []*pbMsg.MsgFormat, GroupMsg []*pbMsg.MsgFormat, MaxSeq int64, MinSeq int64, err error) {
var count int64
session := d.mgoSession.Clone()
if session == nil {
return nil, nil, MaxSeq, MinSeq, errors.New("session == nil")
@@ -76,48 +79,124 @@ func (d *DataBases) GetUserChat(uid string, seqBegin, seqEnd int64) (SingleMsg [
GroupMsg = append(GroupMsg, temp)
}
count++
if count == (seqEnd - seqBegin + 1) {
break
}
}
}
return SingleMsg, GroupMsg, MaxSeq, MinSeq, nil
}
func (d *DataBases) GetMsgBySeqList(uid string, seqList []int64) (SingleMsg []*pbMsg.MsgFormat, GroupMsg []*pbMsg.MsgFormat, MaxSeq int64, MinSeq int64, err error) {
allCount := 0
singleCount := 0
session := d.mgoSession.Clone()
if session == nil {
return nil, nil, MaxSeq, MinSeq, errors.New("session == nil")
}
defer session.Close()
func (d *DataBases) SaveUserChat(uid string, sendTime int64, m proto.Message) error {
c := session.DB(config.Config.Mongo.DBDatabase).C(cChat)
m := func(uid string, seqList []int64) map[string][]int64 {
t := make(map[string][]int64)
for i := 0; i < len(seqList); i++ {
seqUid := getSeqUid(uid, seqList[i])
if value, ok := t[seqUid]; !ok {
var temp []int64
t[seqUid] = append(temp, seqList[i])
} else {
t[seqUid] = append(value, seqList[i])
}
}
return t
}(uid, seqList)
sChat := UserChat{}
pChat := pbMsg.MsgSvrToPushSvrChatMsg{}
for seqUid, value := range m {
if err = c.Find(bson.M{"uid": seqUid}).One(&sChat); err != nil {
log.NewError("", "not find seqUid", seqUid, value, uid, seqList)
continue
}
singleCount = 0
for i := 0; i < len(sChat.Msg); i++ {
temp := new(pbMsg.MsgFormat)
if err = proto.Unmarshal(sChat.Msg[i].Msg, &pChat); err != nil {
log.NewError("", "not find seqUid", seqUid, value, uid, seqList)
return nil, nil, MaxSeq, MinSeq, err
}
if isContainInt64(pChat.RecvSeq, value) {
temp.SendID = pChat.SendID
temp.RecvID = pChat.RecvID
temp.MsgFrom = pChat.MsgFrom
temp.Seq = pChat.RecvSeq
temp.ServerMsgID = pChat.MsgID
temp.SendTime = pChat.SendTime
temp.Content = pChat.Content
temp.ContentType = pChat.ContentType
temp.SenderPlatformID = pChat.PlatformID
temp.ClientMsgID = pChat.ClientMsgID
temp.SenderFaceURL = pChat.SenderFaceURL
temp.SenderNickName = pChat.SenderNickName
if pChat.RecvSeq > MaxSeq {
MaxSeq = pChat.RecvSeq
}
if allCount == 0 {
MinSeq = pChat.RecvSeq
}
if pChat.RecvSeq < MinSeq {
MinSeq = pChat.RecvSeq
}
if pChat.SessionType == constant.SingleChatType {
SingleMsg = append(SingleMsg, temp)
} else {
GroupMsg = append(GroupMsg, temp)
}
allCount++
singleCount++
if singleCount == len(value) {
break
}
}
}
}
return SingleMsg, GroupMsg, MaxSeq, MinSeq, nil
}
func (d *DataBases) SaveUserChat(uid string, sendTime int64, m *pbMsg.MsgSvrToPushSvrChatMsg) error {
var seqUid string
newTime := getCurrentTimestampByMill()
session := d.mgoSession.Clone()
if session == nil {
return errors.New("session == nil")
}
defer session.Close()
log.NewInfo("", "get mgoSession cost time", getCurrentTimestampByMill()-newTime)
c := session.DB(config.Config.Mongo.DBDatabase).C(cChat)
n, err := c.Find(bson.M{"uid": uid}).Count()
seqUid = getSeqUid(uid, m.RecvSeq)
n, err := c.Find(bson.M{"uid": seqUid}).Count()
if err != nil {
return err
}
log.NewInfo("", "find mgo uid cost time", getCurrentTimestampByMill()-newTime)
sMsg := MsgInfo{}
sMsg.SendTime = sendTime
if sMsg.Msg, err = proto.Marshal(m); err != nil {
return err
}
if n == 0 {
sChat := UserChat{}
sChat.UID = uid
sChat.UID = seqUid
sChat.Msg = append(sChat.Msg, sMsg)
err = c.Insert(&sChat)
if err != nil {
return err
}
} else {
err = c.Update(bson.M{"uid": uid}, bson.M{"$push": bson.M{"msg": sMsg}})
err = c.Update(bson.M{"uid": seqUid}, bson.M{"$push": bson.M{"msg": sMsg}})
if err != nil {
return err
}
}
log.NewInfo("", "insert mgo data cost time", getCurrentTimestampByMill()-newTime)
return nil
}
@@ -231,3 +310,22 @@ func (d *DataBases) DelGroupMember(groupID, uid string) error {
return nil
}
func getCurrentTimestampByMill() int64 {
return time.Now().UnixNano() / 1e6
}
func getSeqUid(uid string, seq int64) string {
seqSuffix := seq / singleGocMsgNum
return uid + ":" + strconv.FormatInt(seqSuffix, 10)
}
func isContainInt64(target int64, List []int64) bool {
for _, element := range List {
if target == element {
return true
}
}
return false
}
@@ -1,9 +1,9 @@
package im_mysql_model
import (
"Open_IM/pkg/proto/group"
"Open_IM/pkg/common/db"
"Open_IM/pkg/common/log"
"Open_IM/pkg/proto/group"
"errors"
"time"
)
@@ -3,7 +3,7 @@ package im_mysql_model
import "time"
type User struct {
UID string `gorm:"column:uid"`
UID string `gorm:"column:uid;primaryKey;"`
Name string `gorm:"column:name"`
Icon string `gorm:"column:icon"`
Gender int32 `gorm:"column:gender"`
@@ -5,6 +5,7 @@ import (
"Open_IM/pkg/common/db"
pbAuth "Open_IM/pkg/proto/auth"
"Open_IM/pkg/utils"
"fmt"
_ "github.com/jinzhu/gorm/dialects/mysql"
"time"
)
@@ -18,7 +19,7 @@ func init() {
pb.Name = "AppManager" + utils.IntToString(k+1)
err := UserRegister(&pb)
if err != nil {
panic(err)
fmt.Println("AppManager insert error", err.Error())
}
}
}
+22 -8
View File
@@ -9,6 +9,7 @@ const (
userIncrSeq = "REDIS_USER_INCR_SEQ:" // user incr seq
appleDeviceToken = "DEVICE_TOKEN"
lastGetSeq = "LAST_GET_SEQ"
userMinSeq = "REDIS_USER_MIN_SEQ:"
)
func (d *DataBases) Exec(cmd string, key interface{}, args ...interface{}) (interface{}, error) {
@@ -31,42 +32,55 @@ func (d *DataBases) Exec(cmd string, key interface{}, args ...interface{}) (inte
return con.Do(cmd, params...)
}
//执行用户消息的seq自增操作
//Perform seq auto-increment operation of user messages
func (d *DataBases) IncrUserSeq(uid string) (int64, error) {
key := userIncrSeq + uid
return redis.Int64(d.Exec("INCR", key))
}
//获取最新的seq
func (d *DataBases) GetUserSeq(uid string) (int64, error) {
//Get the largest Seq
func (d *DataBases) GetUserMaxSeq(uid string) (int64, error) {
key := userIncrSeq + uid
return redis.Int64(d.Exec("GET", key))
}
//存储苹果的设备token到redis
//Set the user's minimum seq
func (d *DataBases) SetUserMinSeq(uid string) (err error) {
key := userMinSeq + uid
_, err = d.Exec("SET", key)
return err
}
//Get the smallest Seq
func (d *DataBases) GetUserMinSeq(uid string) (int64, error) {
key := userMinSeq + uid
return redis.Int64(d.Exec("GET", key))
}
//Store Apple's device token to redis
func (d *DataBases) SetAppleDeviceToken(accountAddress, value string) (err error) {
key := appleDeviceToken + accountAddress
_, err = d.Exec("SET", key, value)
return err
}
//删除苹果设备token
//Delete Apple device token
func (d *DataBases) DelAppleDeviceToken(accountAddress string) (err error) {
key := appleDeviceToken + accountAddress
_, err = d.Exec("DEL", key)
return err
}
//记录用户上一次主动拉取Seq的值
//Record the last time the user actively pulled the value of Seq
func (d *DataBases) SetLastGetSeq(uid string) (err error) {
key := lastGetSeq + uid
_, err = d.Exec("SET", key)
return err
}
//获取用户上一次主动拉取Seq的值
//Get the value of the user's last active pull Seq
func (d *DataBases) GetLastGetSeq(uid string) (int64, error) {
key := userIncrSeq + uid
key := lastGetSeq + uid
return redis.Int64(d.Exec("GET", key))
}
+108
View File
@@ -0,0 +1,108 @@
/*
** description("Send logs to elasticsearch hook").
** copyright('tuoyun,www.tuoyun.net').
** author("fg,Gordon@tuoyun.net").
** time(2021/3/26 17:05).
*/
package log
import (
"Open_IM/pkg/common/config"
"context"
"fmt"
elasticV7 "github.com/olivere/elastic/v7"
"github.com/sirupsen/logrus"
"log"
"os"
"strings"
"time"
)
//esHook CUSTOMIZED ES hook
type esHook struct {
moduleName string
client *elasticV7.Client
}
//newEsHook Initialization
func newEsHook(moduleName string) *esHook {
//https://github.com/sohlich/elogrus
//client, err := elastic.NewClient(elastic.SetURL("http://localhost:9200"))
//if err != nil {
// log.Panic(err)
//}
//hook, err := elogrus.NewAsyncElasticHook(client, "localhost", logrus.DebugLevel, "mylog")
//if err != nil {
// log.Panic(err)
//}
es, err := elasticV7.NewClient(
elasticV7.SetURL(config.Config.Log.ElasticSearchAddr...),
elasticV7.SetBasicAuth(config.Config.Log.ElasticSearchUser, config.Config.Log.ElasticSearchPassword),
elasticV7.SetSniff(false),
elasticV7.SetHealthcheckInterval(60*time.Second),
elasticV7.SetErrorLog(log.New(os.Stderr, "ES:", log.LstdFlags)),
)
if err != nil {
log.Fatal("failed to create Elastic V7 Client: ", err)
}
//info, code, err := es.Ping(logConfig.ElasticSearch.EsAddr[0]).Do(context.Background())
//if err != nil {
// panic(err)
//}
//fmt.Printf("Elasticsearch returned with code %d and version %s\n", code, info.Version.Number)
//
//esversion, err := es.ElasticsearchVersion(logConfig.ElasticSearch.EsAddr[0])
//if err != nil {
// panic(err)
//}
//fmt.Printf("Elasticsearch version %s\n", esversion)
return &esHook{client: es, moduleName: moduleName}
}
//Fire log hook interface 方法
func (hook *esHook) Fire(entry *logrus.Entry) error {
doc := newEsLog(entry)
go hook.sendEs(doc)
return nil
}
//Levels log hook interface 方法,此hook影响的日志
func (hook *esHook) Levels() []logrus.Level {
return logrus.AllLevels
}
//sendEs 异步发送日志到es
func (hook *esHook) sendEs(doc appLogDocModel) {
defer func() {
if r := recover(); r != nil {
fmt.Println("send entry to es failed: ", r)
}
}()
_, err := hook.client.Index().Index(hook.moduleName).Type(doc.indexName()).BodyJson(doc).Do(context.Background())
if err != nil {
log.Println(err)
}
}
//appLogDocModel es model
type appLogDocModel map[string]interface{}
func newEsLog(e *logrus.Entry) appLogDocModel {
ins := make(map[string]interface{})
ins["level"] = strings.ToUpper(e.Level.String())
ins["time"] = e.Time.Format("2006-01-02 15:04:05")
for kk, vv := range e.Data {
ins[kk] = vv
}
ins["tipInfo"] = e.Message
return ins
}
// indexName es index name 时间分割
func (m *appLogDocModel) indexName() string {
return time.Now().Format("2006-01-02")
}
+60
View File
@@ -0,0 +1,60 @@
/*
** description("get the name and line number of the calling file hook").
** copyright('tuoyun,www.tuoyun.net').
** author("fg,Gordon@tuoyun.net").
** time(2021/3/16 11:26).
*/
package log
import (
"fmt"
"github.com/sirupsen/logrus"
"runtime"
"strings"
)
type fileHook struct{}
func newFileHook() *fileHook {
return &fileHook{}
}
func (f *fileHook) Levels() []logrus.Level {
return logrus.AllLevels
}
func (f *fileHook) Fire(entry *logrus.Entry) error {
entry.Data["FilePath"] = findCaller(5)
return nil
}
func findCaller(skip int) string {
file := ""
line := 0
for i := 0; i < 10; i++ {
file, line = getCaller(skip + i)
if !strings.HasPrefix(file, "log") {
break
}
}
return fmt.Sprintf("%s:%d", file, line)
}
func getCaller(skip int) (string, int) {
_, file, line, ok := runtime.Caller(skip)
if !ok {
return "", 0
}
n := 0
for i := len(file) - 1; i > 0; i-- {
if file[i] == '/' {
n++
if n >= 2 {
file = file[i+1:]
break
}
}
}
return file, line
}
+205
View File
@@ -0,0 +1,205 @@
package log
import (
"Open_IM/pkg/common/config"
"bufio"
"fmt"
nested "github.com/antonfisher/nested-logrus-formatter"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"github.com/rifflock/lfshook"
"github.com/sirupsen/logrus"
"os"
"time"
)
var logger *Logger
type Logger struct {
*logrus.Logger
Pid int
}
func init() {
logger = loggerInit("")
}
func NewPrivateLog(moduleName string) {
logger = loggerInit(moduleName)
}
func loggerInit(moduleName string) *Logger {
var logger = logrus.New()
//All logs will be printed
logger.SetLevel(logrus.Level(config.Config.Log.RemainLogLevel))
//Close std console output
src, err := os.OpenFile(os.DevNull, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
panic(err)
}
writer := bufio.NewWriter(src)
logger.SetOutput(writer)
//Log Console Print Style Setting
logger.SetFormatter(&nested.Formatter{
TimestampFormat: "2006-01-02 15:04:05.000",
HideKeys: false,
FieldsOrder: []string{"PID", "FilePath", "OperationID"},
})
//File name and line number display hook
logger.AddHook(newFileHook())
//Send logs to elasticsearch hook
if config.Config.Log.ElasticSearchSwitch {
logger.AddHook(newEsHook(moduleName))
}
//Log file segmentation hook
hook := NewLfsHook(time.Duration(config.Config.Log.RotationTime)*time.Hour, config.Config.Log.RemainRotationCount, moduleName)
logger.AddHook(hook)
return &Logger{
logger,
os.Getpid(),
}
}
func NewLfsHook(rotationTime time.Duration, maxRemainNum uint, moduleName string) logrus.Hook {
lfsHook := lfshook.NewHook(lfshook.WriterMap{
logrus.DebugLevel: initRotateLogs(rotationTime, maxRemainNum, "debug", moduleName),
logrus.InfoLevel: initRotateLogs(rotationTime, maxRemainNum, "info", moduleName),
logrus.WarnLevel: initRotateLogs(rotationTime, maxRemainNum, "warn", moduleName),
logrus.ErrorLevel: initRotateLogs(rotationTime, maxRemainNum, "error", moduleName),
}, &nested.Formatter{
TimestampFormat: "2006-01-02 15:04:05.000",
HideKeys: false,
FieldsOrder: []string{"PID", "FilePath", "OperationID"},
})
return lfsHook
}
func initRotateLogs(rotationTime time.Duration, maxRemainNum uint, level string, moduleName string) *rotatelogs.RotateLogs {
if moduleName != "" {
moduleName = moduleName + "."
}
writer, err := rotatelogs.New(
config.Config.Log.StorageLocation+moduleName+level+"."+"%Y-%m-%d",
rotatelogs.WithRotationTime(rotationTime),
rotatelogs.WithRotationCount(maxRemainNum),
)
if err != nil {
panic(err)
} else {
return writer
}
}
//Deprecated
func Info(token, OperationID, format string, args ...interface{}) {
logger.WithFields(logrus.Fields{
"PID": logger.Pid,
"OperationID": OperationID,
}).Infof(format, args...)
}
//Deprecated
func Error(token, OperationID, format string, args ...interface{}) {
logger.WithFields(logrus.Fields{
"PID": logger.Pid,
"OperationID": OperationID,
}).Errorf(format, args...)
}
//Deprecated
func Debug(token, OperationID, format string, args ...interface{}) {
logger.WithFields(logrus.Fields{
"PID": logger.Pid,
"OperationID": OperationID,
}).Debugf(format, args...)
}
//Deprecated
func Warning(token, OperationID, format string, args ...interface{}) {
logger.WithFields(logrus.Fields{
"PID": logger.Pid,
"OperationID": OperationID,
}).Warningf(format, args...)
}
//Deprecated
func InfoByArgs(format string, args ...interface{}) {
logger.WithFields(logrus.Fields{}).Infof(format, args)
}
//Deprecated
func ErrorByArgs(format string, args ...interface{}) {
logger.WithFields(logrus.Fields{}).Errorf(format, args...)
}
//Print log information in k, v format,
//kv is best to appear in pairs. tipInfo is the log prompt information for printing,
//and kv is the key and value for printing.
//Deprecated
func InfoByKv(tipInfo, OperationID string, args ...interface{}) {
fields := make(logrus.Fields)
argsHandle(OperationID, fields, args)
logger.WithFields(fields).Info(tipInfo)
}
//Deprecated
func ErrorByKv(tipInfo, OperationID string, args ...interface{}) {
fields := make(logrus.Fields)
argsHandle(OperationID, fields, args)
logger.WithFields(fields).Error(tipInfo)
}
//Deprecated
func DebugByKv(tipInfo, OperationID string, args ...interface{}) {
fields := make(logrus.Fields)
argsHandle(OperationID, fields, args)
logger.WithFields(fields).Debug(tipInfo)
}
//Deprecated
func WarnByKv(tipInfo, OperationID string, args ...interface{}) {
fields := make(logrus.Fields)
argsHandle(OperationID, fields, args)
logger.WithFields(fields).Warn(tipInfo)
}
//internal method
func argsHandle(OperationID string, fields logrus.Fields, args []interface{}) {
for i := 0; i < len(args); i += 2 {
if i+1 < len(args) {
fields[fmt.Sprintf("%v", args[i])] = args[i+1]
} else {
fields[fmt.Sprintf("%v", args[i])] = ""
}
}
fields["OperationID"] = OperationID
fields["PID"] = logger.Pid
}
func NewInfo(OperationID string, args ...interface{}) {
logger.WithFields(logrus.Fields{
"OperationID": OperationID,
"PID": logger.Pid,
}).Infoln(args)
}
func NewError(OperationID string, args ...interface{}) {
logger.WithFields(logrus.Fields{
"OperationID": OperationID,
"PID": logger.Pid,
}).Errorln(args)
}
func NewDebug(OperationID string, args ...interface{}) {
logger.WithFields(logrus.Fields{
"OperationID": OperationID,
"PID": logger.Pid,
}).Debugln(args)
}
func NewWarn(OperationID string, args ...interface{}) {
logger.WithFields(logrus.Fields{
"OperationID": OperationID,
"PID": logger.Pid,
}).Warnln(args)
}
+57
View File
@@ -0,0 +1,57 @@
/*
** description("").
** copyright('tuoyun,www.tuoyun.net').
** author("fg,Gordon@tuoyun.net").
** time(2021/2/22 11:52).
*/
package log
import (
"strconv"
"time"
)
const (
TimeOffset = 8 * 3600 //8 hour offset
HalfOffset = 12 * 3600 //Half-day hourly offset
)
//Get the current timestamp
func GetCurrentTimestamp() int64 {
return time.Now().Unix()
}
//Get the current 0 o'clock timestamp
func GetCurDayZeroTimestamp() int64 {
timeStr := time.Now().Format("2006-01-02")
t, _ := time.Parse("2006-01-02", timeStr)
return t.Unix() - TimeOffset
}
//Get the timestamp at 12 o'clock on the day
func GetCurDayHalfTimestamp() int64 {
return GetCurDayZeroTimestamp() + HalfOffset
}
//Get the formatted time at 0 o'clock of the day, the format is "2006-01-02_00-00-00"
func GetCurDayZeroTimeFormat() string {
return time.Unix(GetCurDayZeroTimestamp(), 0).Format("2006-01-02_15-04-05")
}
//Get the formatted time at 12 o'clock of the day, the format is "2006-01-02_12-00-00"
func GetCurDayHalfTimeFormat() string {
return time.Unix(GetCurDayZeroTimestamp()+HalfOffset, 0).Format("2006-01-02_15-04-05")
}
func GetTimeStampByFormat(datetime string) string {
timeLayout := "2006-01-02 15:04:05" //转化所需模板
loc, _ := time.LoadLocation("Local") //获取时区
tmp, _ := time.ParseInLocation(timeLayout, datetime, loc)
timestamp := tmp.Unix() //转化为时间戳 类型是int64
return strconv.FormatInt(timestamp, 10)
}
func TimeStringFormatTimeUnix(timeFormat string, timeSrc string) int64 {
tm, _ := time.Parse(timeFormat, timeSrc)
return tm.Unix()
}
@@ -3,11 +3,11 @@ package multi_terminal_login
import (
"Open_IM/internal/push/content_struct"
"Open_IM/internal/push/logic"
pbChat "Open_IM/pkg/proto/chat"
"Open_IM/pkg/common/config"
"Open_IM/pkg/common/constant"
"Open_IM/pkg/common/db"
"Open_IM/pkg/common"
pbChat "Open_IM/pkg/proto/chat"
"Open_IM/pkg/utils"
)
func MultiTerminalLoginChecker(uid, token string, platformID int32) error {