channel.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. package chat
  2. import (
  3. "bet24.com/log"
  4. "bet24.com/redis"
  5. user "bet24.com/servers/micros/userservices/proto"
  6. "encoding/json"
  7. "fmt"
  8. "sort"
  9. "strconv"
  10. "strings"
  11. "time"
  12. )
  13. func SplitToString(a []int, sep string) string {
  14. if len(a) == 0 {
  15. return ""
  16. }
  17. b := make([]string, len(a))
  18. for i, v := range a {
  19. b[i] = strconv.Itoa(v)
  20. }
  21. return strings.Join(b, sep)
  22. }
  23. func getChannelKey(userIds []int) string {
  24. sort.Slice(userIds, func(i, j int) bool {
  25. return userIds[i] < userIds[j]
  26. })
  27. return SplitToString(userIds, "+")
  28. }
  29. const CHAT_TIME_OUT = 1800
  30. const MAX_ARCHIVE_MESSAGE = 20
  31. const MAX_ARCHIVE_TIME = 432000 // 5天
  32. const MAX_MESSAGE_LEN = 256
  33. const ONE_DAY = 86400
  34. type ChannelUser struct {
  35. UserId int
  36. NickName string
  37. FaceId int
  38. FaceUrl string
  39. ReadIndex int // 实际读到哪条了
  40. getIndex int // 取内容标签,用户退出重进后,需要拉所有记录
  41. ClearIndex int
  42. Decorations []user.UserDecoration
  43. Vip int
  44. VipPoint int
  45. VipExpire int
  46. }
  47. type chatMsg struct {
  48. Sender int
  49. Message string
  50. SendTime string
  51. Index int
  52. MsgType int
  53. }
  54. type channel struct {
  55. //userIds []int // 参与的用户
  56. Key string
  57. Users []*ChannelUser
  58. MessageList []chatMsg
  59. lastAck time.Time
  60. ChatIndex int
  61. }
  62. func newChannel(users []*ChannelUser) *channel {
  63. c := new(channel)
  64. c.Users = users
  65. if len(c.Users) >= 2 {
  66. var userIds []int
  67. for _, v := range users {
  68. userIds = append(userIds, v.UserId)
  69. }
  70. c.Key = getChannelKey(userIds)
  71. c.restore()
  72. for _, v := range users {
  73. c.updateUser(v)
  74. }
  75. }
  76. c.touch()
  77. return c
  78. }
  79. func createChannelByKey(key string) *channel {
  80. c := new(channel)
  81. c.Key = key
  82. if !c.restore() {
  83. return nil
  84. }
  85. return c
  86. }
  87. func (c *channel) isUserExist(userId int) bool {
  88. for _, v := range c.Users {
  89. if v.UserId == userId {
  90. return true
  91. }
  92. }
  93. return false
  94. }
  95. func (c *channel) isIdle() bool {
  96. return int(time.Now().Sub(c.lastAck).Seconds()) >= CHAT_TIME_OUT
  97. }
  98. func (c *channel) addUser(userId int, nickName string, faceId int, faceUrl string) {
  99. if c.isUserExist(userId) {
  100. log.Release("channel.addUser userId[%d] exist", userId)
  101. return
  102. }
  103. channelUser := &ChannelUser{
  104. UserId: userId,
  105. NickName: nickName,
  106. FaceId: faceId,
  107. FaceUrl: faceUrl,
  108. }
  109. usr := user.GetUserInfo(userId)
  110. if usr != nil {
  111. channelUser.Vip = usr.Vip
  112. channelUser.VipPoint = usr.VipPoint
  113. channelUser.VipExpire = usr.VipExpire
  114. channelUser.Decorations = usr.Decorations
  115. }
  116. c.Users = append(c.Users, channelUser)
  117. if len(c.Users) >= 2 {
  118. var userIds []int
  119. for _, v := range c.Users {
  120. userIds = append(userIds, v.UserId)
  121. }
  122. c.Key = getChannelKey(userIds)
  123. c.restore()
  124. }
  125. c.touch()
  126. }
  127. func (c *channel) updateUser(userInfo *ChannelUser) {
  128. if userInfo.NickName == "" {
  129. return
  130. }
  131. for _, v := range c.Users {
  132. if v.UserId == userInfo.UserId {
  133. v.NickName = userInfo.NickName
  134. v.FaceId = userInfo.FaceId
  135. v.FaceUrl = userInfo.FaceUrl
  136. }
  137. }
  138. }
  139. func (c *channel) touch() {
  140. c.lastAck = time.Now()
  141. }
  142. func (c *channel) addChat(userId int, message string, msgType int) {
  143. if !c.isUserExist(userId) {
  144. log.Release("channel.addChat userId %d not exist", userId)
  145. return
  146. }
  147. if len(message) > MAX_MESSAGE_LEN && msgType == 0 {
  148. message = message[:MAX_MESSAGE_LEN]
  149. }
  150. c.MessageList = append(c.MessageList, chatMsg{
  151. Sender: userId,
  152. Message: message,
  153. SendTime: time.Now().Format("2006-01-02 15:04:05"),
  154. Index: c.ChatIndex,
  155. MsgType: msgType,
  156. })
  157. c.ChatIndex++
  158. c.touch()
  159. }
  160. func (c *channel) getClearReadIndex(clearIndex, readIndex int) int {
  161. if clearIndex == 0 {
  162. return readIndex
  163. }
  164. ret := len(c.MessageList)
  165. for i := 0; i < len(c.MessageList); i++ {
  166. if c.MessageList[i].Index >= clearIndex {
  167. ret = i
  168. break
  169. }
  170. }
  171. if ret > readIndex {
  172. return ret
  173. }
  174. return readIndex
  175. }
  176. func (c *channel) getChatByUser(userId int) string {
  177. // 获取用户当前读取
  178. var ch channel
  179. ch.Key = c.Key
  180. readIndex := 0
  181. needUserInfo := false
  182. for _, v := range c.Users {
  183. if v.UserId == userId {
  184. readIndex = v.getIndex
  185. needUserInfo = readIndex == 0
  186. // 判断一下是否Clear
  187. readIndex = c.getClearReadIndex(v.ClearIndex, readIndex)
  188. v.ReadIndex = len(c.MessageList)
  189. v.getIndex = v.ReadIndex
  190. }
  191. }
  192. // 是否需要玩家信息?
  193. if needUserInfo {
  194. for _, v := range c.Users {
  195. if v.UserId == userId {
  196. continue
  197. }
  198. ch.Users = append(ch.Users, v)
  199. }
  200. }
  201. if readIndex > len(c.MessageList) {
  202. readIndex = len(c.MessageList)
  203. }
  204. ch.MessageList = c.MessageList[readIndex:]
  205. d, _ := json.Marshal(ch)
  206. return string(d)
  207. }
  208. func (c *channel) dump() {
  209. log.Release("channel.dump[%s] ChatIndex[%d] ----------", c.Key, c.ChatIndex)
  210. defer log.Release("channel.dump end ++++++++++++++++")
  211. log.Release(" userlist")
  212. for _, v := range c.Users {
  213. log.Release(" [%d]%s ReadIndex[%d] ClearIndex[%d]Vip[%d]", v.UserId, v.NickName, v.ReadIndex, v.ClearIndex, v.Vip)
  214. }
  215. log.Release(" chatlist")
  216. for _, v := range c.MessageList {
  217. log.Release(" [%d][%d]%s", v.Index, v.Sender, v.Message)
  218. }
  219. }
  220. func (c *channel) isInvolved(userId int) bool {
  221. for _, v := range c.Users {
  222. if v.UserId == userId {
  223. return true
  224. }
  225. }
  226. return false
  227. }
  228. func (c *channel) release() {
  229. count := len(c.MessageList) - MAX_ARCHIVE_MESSAGE
  230. if count > 0 {
  231. c.MessageList = c.MessageList[count:]
  232. for _, v := range c.Users {
  233. v.ReadIndex -= count
  234. if v.ReadIndex < 0 {
  235. v.ReadIndex = 0
  236. }
  237. //v.getIndex = v.ReadIndex
  238. }
  239. }
  240. c.archive()
  241. }
  242. func (c *channel) getRedisKey() string {
  243. return fmt.Sprintf("channel:%s", c.Key)
  244. }
  245. func (c *channel) archive() {
  246. d, _ := json.Marshal(c)
  247. redis.String_SetEx(c.getRedisKey(), string(d), MAX_ARCHIVE_TIME)
  248. }
  249. func (c *channel) removeFromRedis() {
  250. redis.Key_Del(c.getRedisKey())
  251. }
  252. func (c *channel) restore() bool {
  253. data, ok := redis.String_Get(c.getRedisKey())
  254. if !ok || data == "" {
  255. return false
  256. }
  257. json.Unmarshal([]byte(data), &c)
  258. for _, v := range c.Users {
  259. usr := user.GetUserInfo(v.UserId)
  260. if usr != nil {
  261. v.Vip = usr.Vip
  262. v.VipPoint = usr.VipPoint
  263. v.VipExpire = usr.VipExpire
  264. v.Decorations = usr.Decorations
  265. }
  266. v.ReadIndex = 0
  267. v.getIndex = 0
  268. }
  269. c.touch()
  270. return true
  271. }
  272. func (c *channel) onUserExit(userId int) {
  273. for _, v := range c.Users {
  274. if v.UserId == userId {
  275. v.getIndex = 0
  276. return
  277. }
  278. }
  279. log.Release("channel.onUserExit user[%d] not involve", userId)
  280. }
  281. func (c *channel) getNewChatCount(userId int) int {
  282. ret := 0
  283. for _, v := range c.Users {
  284. if v.UserId == userId {
  285. v.ReadIndex = c.getClearReadIndex(v.ClearIndex, v.ReadIndex)
  286. ret = len(c.MessageList) - v.ReadIndex
  287. }
  288. }
  289. if ret < 0 {
  290. ret = 0
  291. }
  292. return ret
  293. }
  294. func (c *channel) getLatestMessage() string {
  295. if len(c.MessageList) == 0 {
  296. return ""
  297. }
  298. return c.MessageList[len(c.MessageList)-1].Message
  299. }
  300. func (c *channel) getLatestTime() string {
  301. if len(c.MessageList) == 0 {
  302. return ""
  303. }
  304. return c.MessageList[len(c.MessageList)-1].SendTime
  305. }
  306. func (c *channel) getLatestMessageType() int {
  307. if len(c.MessageList) == 0 {
  308. return 0
  309. }
  310. return c.MessageList[len(c.MessageList)-1].MsgType
  311. }
  312. func (c *channel) getInfo() string {
  313. var ch channel
  314. ch.Key = c.Key
  315. for _, v := range c.Users {
  316. ch.Users = append(ch.Users, v)
  317. }
  318. d, _ := json.Marshal(ch)
  319. return string(d)
  320. }
  321. func (c *channel) userClear(userId int) {
  322. log.Debug("channel.userClear %d", userId)
  323. for _, v := range c.Users {
  324. if v.UserId == userId {
  325. v.ClearIndex = c.ChatIndex
  326. return
  327. }
  328. }
  329. }