You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

119 lines
2.8 KiB

  1. package device
  2. import (
  3. "context"
  4. "egg-im/internal/business/comm/utils"
  5. "egg-im/pkg/db"
  6. "egg-im/pkg/gerrors"
  7. "egg-im/pkg/logger"
  8. "egg-im/pkg/pb"
  9. "egg-im/pkg/rpc"
  10. "errors"
  11. "fmt"
  12. "time"
  13. "go.uber.org/zap"
  14. )
  15. type deviceService struct{}
  16. var DeviceService = new(deviceService)
  17. const (
  18. SignInKey = "egg_im_sign_in:%s" // 占位符: key的第一个字母
  19. SignInExpire = 5 * time.Second
  20. )
  21. // Register 注册设备
  22. func (*deviceService) Register(ctx context.Context, device *Device) error {
  23. err := DeviceDao.Save(device)
  24. if err != nil {
  25. return err
  26. }
  27. return nil
  28. }
  29. // SignIn 长连接登录
  30. func (*deviceService) SignIn(ctx context.Context, userId, deviceId int64, token string, connAddr string, clientAddr string) error {
  31. //TODO::限制操作
  32. cacheKey := fmt.Sprintf(SignInKey, utils.Int64ToStr(userId))
  33. if db.RedisUtil.Exists(cacheKey) {
  34. utils.FilePutContents("sign_in", utils.SerializeStr(map[string]interface{}{
  35. "user_id": userId,
  36. "device_id": deviceId,
  37. "token": token,
  38. "conn_addr": connAddr,
  39. "client_addr": clientAddr,
  40. "cache_key": cacheKey,
  41. }))
  42. return errors.New("限频!!!")
  43. } else {
  44. err := db.RedisUtil.Set(cacheKey, "already", SignInExpire)
  45. if err != nil {
  46. return gerrors.WrapError(err)
  47. }
  48. }
  49. _, err := rpc.GetBusinessIntClient().Auth(ctx, &pb.AuthReq{UserId: userId, DeviceId: deviceId, Token: token})
  50. if err != nil {
  51. return err
  52. }
  53. // 标记用户在设备上登录
  54. device, err := DeviceRepo.Get(deviceId)
  55. if err != nil {
  56. return err
  57. }
  58. if device == nil {
  59. return nil
  60. }
  61. device.Online(userId, connAddr, clientAddr)
  62. err = DeviceRepo.Save(device)
  63. if err != nil {
  64. return err
  65. }
  66. return nil
  67. }
  68. // Auth 权限验证
  69. func (*deviceService) Auth(ctx context.Context, userId, deviceId int64, token string) error {
  70. _, err := rpc.GetBusinessIntClient().Auth(ctx, &pb.AuthReq{UserId: userId, DeviceId: deviceId, Token: token})
  71. if err != nil {
  72. return err
  73. }
  74. return nil
  75. }
  76. func (*deviceService) ListOnlineByUserId(ctx context.Context, userId int64) ([]*pb.Device, error) {
  77. devices, err := DeviceRepo.ListOnlineByUserId(userId)
  78. if err != nil {
  79. return nil, err
  80. }
  81. pbDevices := make([]*pb.Device, len(devices))
  82. for i := range devices {
  83. pbDevices[i] = devices[i].ToProto()
  84. }
  85. return pbDevices, nil
  86. }
  87. // ServerStop connect服务停止,需要将连接在这台connect上的设备标记为下线
  88. func (*deviceService) ServerStop(ctx context.Context, connAddr string) error {
  89. devices, err := DeviceRepo.ListOnlineByConnAddr(connAddr)
  90. if err != nil {
  91. return err
  92. }
  93. for i := range devices {
  94. // 因为是异步修改设备转台,要避免设备重连,导致状态不一致
  95. err = DeviceRepo.UpdateStatusOffline(devices[i])
  96. if err != nil {
  97. logger.Logger.Error("DeviceRepo.Save error", zap.Any("device", devices[i]), zap.Error(err))
  98. }
  99. time.Sleep(2 * time.Millisecond)
  100. }
  101. return nil
  102. }