message.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package server
  2. import (
  3. "encoding/json"
  4. "github.com/mitchellh/mapstructure"
  5. )
  6. type MessageType = uint8
  7. type ChatingContentType = uint8
  8. const (
  9. MessageTypeChating MessageType = 1 + iota // MessageTypeDialogue 语聊消息
  10. MessageTypeReply // MessageTypeReply 回复消息
  11. MessageTypeError // MessageTypeError 错误消息,当服务器出现错误时,会发送此消息
  12. MessageTypePing // MessageTypePing ping
  13. MessageTypePong // MessageTypePong pong
  14. MessageTypeEmpty // MessageTypeEmpty 空消息
  15. )
  16. const (
  17. ChatingContentTypeText ChatingContentType = 1 + iota // ChatingContentTypeText 语聊文字消息
  18. ChatingContentTypeMetadata // ChatingContentTypeMetadata 媒体文件消息
  19. )
  20. const (
  21. PingPayload byte = 0x70
  22. )
  23. type Message struct {
  24. Type MessageType `json:"type"`
  25. MessageId string `json:"messageId"` // MessageId 当前消息的Id
  26. Content any `json:"content"` // Content 内容
  27. receiver string `json:"-"` // Receiver 消息接受者
  28. }
  29. // ChatingContent to client dialogue message
  30. type ChatingContent struct {
  31. Receiver string `json:"receiver"`
  32. PayloadType ChatingContentType `json:"payloadType"`
  33. Payload any `json:"payload"`
  34. }
  35. // ContentText received a text message from the client
  36. type ContentText struct {
  37. Raw string `json:"raw"`
  38. }
  39. // ContentMetadata received media file message from client
  40. type ContentMetadata struct {
  41. Url string `json:"url"` // Url 文件地址
  42. FileType string `json:"fileType"` // FileType 文件类型
  43. Duration uint `json:"duration"` // Duration 视频/语音时长
  44. }
  45. // COntentReply to client after receiving the message
  46. type ContentReply struct {
  47. MessageId string `json:"messageId"` // MessageId 消息ID
  48. ReplyId string `json:"replyId"` // ReplyId 回复ID
  49. }
  50. type ContentError struct {
  51. Err string `json:"err"`
  52. }
  53. func (m *Message) IsNeedReply() bool {
  54. return m.MessageId != ""
  55. }
  56. func deserializeMessage(bytes []byte) *Message {
  57. if len(bytes) == 0 {
  58. return emptyMessage()
  59. }
  60. if bytes[0] == PingPayload {
  61. return pingMessage()
  62. }
  63. var message Message
  64. _ = json.Unmarshal(bytes, &message)
  65. switch message.Type {
  66. // Is it a chating message
  67. case MessageTypeChating:
  68. var chatingContent ChatingContent
  69. mapstructure.Decode(message.Content, &chatingContent)
  70. message.Content = chatingContent
  71. }
  72. return &message
  73. }
  74. func serializationMessage(message *Message) []byte {
  75. bytes, _ := json.Marshal(message)
  76. return bytes
  77. }
  78. // newReplyMessage new a to client reply message
  79. func newReplyMessage(messageId string) *Message {
  80. return &Message{MessageId: messageId, Type: MessageTypeReply}
  81. }
  82. func pingMessage() *Message {
  83. return &Message{Type: MessageTypePing}
  84. }
  85. func pongMessage() *Message {
  86. return &Message{Type: MessageTypePong}
  87. }
  88. func emptyMessage() *Message {
  89. return &Message{Type: MessageTypeEmpty}
  90. }