message-sse.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package controller
  2. import (
  3. "github.com/gin-gonic/gin"
  4. "io"
  5. "message-pusher/model"
  6. "sync"
  7. )
  8. var messageChanBufferSize = 10
  9. var messageChanStore struct {
  10. Map map[int]*chan *model.Message
  11. Mutex sync.RWMutex
  12. }
  13. func messageChanStoreAdd(messageChan *chan *model.Message, userId int) {
  14. messageChanStore.Mutex.Lock()
  15. defer messageChanStore.Mutex.Unlock()
  16. messageChanStore.Map[userId] = messageChan
  17. }
  18. func messageChanStoreRemove(userId int) {
  19. messageChanStore.Mutex.Lock()
  20. defer messageChanStore.Mutex.Unlock()
  21. delete(messageChanStore.Map, userId)
  22. }
  23. func init() {
  24. messageChanStore.Map = make(map[int]*chan *model.Message)
  25. }
  26. func syncMessageToUser(message *model.Message, userId int) {
  27. messageChanStore.Mutex.RLock()
  28. defer messageChanStore.Mutex.RUnlock()
  29. messageChan, ok := messageChanStore.Map[userId]
  30. if !ok {
  31. return
  32. }
  33. *messageChan <- message
  34. }
  35. func GetNewMessages(c *gin.Context) {
  36. userId := c.GetInt("id")
  37. messageChan := make(chan *model.Message, messageChanBufferSize)
  38. messageChanStoreAdd(&messageChan, userId)
  39. c.Stream(func(w io.Writer) bool {
  40. if msg, ok := <-messageChan; ok {
  41. c.SSEvent("message", *msg)
  42. return true
  43. }
  44. return false
  45. })
  46. messageChanStoreRemove(userId)
  47. close(messageChan)
  48. }