golang-im聊天
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

2 anos atrás
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package main
  2. import (
  3. "fmt"
  4. "gim/pkg/pb"
  5. "gim/pkg/util"
  6. "io/ioutil"
  7. "net/http"
  8. "time"
  9. "github.com/gorilla/websocket"
  10. "google.golang.org/protobuf/proto"
  11. )
  12. func main() {
  13. client := WSClient{}
  14. fmt.Println("input UserId,DeviceId,SyncSequence")
  15. fmt.Scanf("%d %d %d", &client.UserId, &client.DeviceId, &client.Seq)
  16. client.Start()
  17. select {}
  18. }
  19. type WSClient struct {
  20. UserId int64
  21. DeviceId int64
  22. Seq int64
  23. Conn *websocket.Conn
  24. }
  25. func (c *WSClient) Start() {
  26. conn, resp, err := websocket.DefaultDialer.Dial("ws://111.229.238.28:8081/ws", http.Header{})
  27. if err != nil {
  28. fmt.Println("dial error", err)
  29. return
  30. }
  31. bytes, err := ioutil.ReadAll(resp.Body)
  32. if err != nil {
  33. fmt.Println(err)
  34. return
  35. }
  36. fmt.Println(string(bytes))
  37. c.Conn = conn
  38. c.SignIn()
  39. c.SyncTrigger()
  40. go c.Heartbeat()
  41. go c.Receive()
  42. }
  43. func (c *WSClient) Output(pt pb.PackageType, requestId int64, message proto.Message) {
  44. var input = pb.Input{
  45. Type: pt,
  46. RequestId: requestId,
  47. }
  48. if message != nil {
  49. bytes, err := proto.Marshal(message)
  50. if err != nil {
  51. fmt.Println(err)
  52. return
  53. }
  54. input.Data = bytes
  55. }
  56. writeBytes, err := proto.Marshal(&input)
  57. if err != nil {
  58. fmt.Println(err)
  59. return
  60. }
  61. err = c.Conn.WriteMessage(websocket.BinaryMessage, writeBytes)
  62. if err != nil {
  63. fmt.Println(err)
  64. }
  65. }
  66. func (c *WSClient) SignIn() {
  67. signIn := pb.SignInInput{
  68. UserId: c.UserId,
  69. DeviceId: c.DeviceId,
  70. Token: "0",
  71. }
  72. c.Output(pb.PackageType_PT_SIGN_IN, time.Now().UnixNano(), &signIn)
  73. }
  74. func (c *WSClient) SyncTrigger() {
  75. c.Output(pb.PackageType_PT_SYNC, time.Now().UnixNano(), &pb.SyncInput{Seq: c.Seq})
  76. }
  77. func (c *WSClient) Heartbeat() {
  78. ticker := time.NewTicker(time.Minute * 4)
  79. for range ticker.C {
  80. c.Output(pb.PackageType_PT_HEARTBEAT, time.Now().UnixNano(), nil)
  81. fmt.Println("心跳发送")
  82. }
  83. }
  84. func (c *WSClient) Receive() {
  85. for {
  86. _, bytes, err := c.Conn.ReadMessage()
  87. if err != nil {
  88. fmt.Println(err)
  89. return
  90. }
  91. c.HandlePackage(bytes)
  92. }
  93. }
  94. func (c *WSClient) HandlePackage(bytes []byte) {
  95. var output pb.Output
  96. err := proto.Unmarshal(bytes, &output)
  97. if err != nil {
  98. fmt.Println(err)
  99. return
  100. }
  101. switch output.Type {
  102. case pb.PackageType_PT_HEARTBEAT:
  103. fmt.Println("心跳响应")
  104. case pb.PackageType_PT_SYNC:
  105. fmt.Println("离线消息同步开始------")
  106. syncResp := pb.SyncOutput{}
  107. err := proto.Unmarshal(output.Data, &syncResp)
  108. if err != nil {
  109. fmt.Println(err)
  110. return
  111. }
  112. fmt.Println("离线消息同步响应:code", output.Code, "message:", output.Message)
  113. fmt.Printf("%+v \n", &output)
  114. for _, msg := range syncResp.Messages {
  115. fmt.Printf("消息:发送者类型:%d 发送者id:%d 接收者类型:%d 接收者id:%d 消息内容:%+v seq:%d \n",
  116. msg.Sender.SenderId, msg.Sender.SenderId, msg.ReceiverType, msg.ReceiverId, util.FormatMessage(msg.MessageType, msg.MessageContent), msg.Seq)
  117. c.Seq = msg.Seq
  118. }
  119. ack := pb.MessageACK{
  120. DeviceAck: c.Seq,
  121. ReceiveTime: util.UnixMilliTime(time.Now()),
  122. }
  123. c.Output(pb.PackageType_PT_MESSAGE, output.RequestId, &ack)
  124. fmt.Println("离线消息同步结束------")
  125. case pb.PackageType_PT_MESSAGE:
  126. message := pb.MessageSend{}
  127. err := proto.Unmarshal(output.Data, &message)
  128. if err != nil {
  129. fmt.Println(err)
  130. return
  131. }
  132. msg := message.Message
  133. fmt.Printf("消息:发送者类型:%d 发送者id:%d 接收者类型:%d 接收者id:%d 消息内容:%+v seq:%d \n",
  134. msg.Sender.SenderType, msg.Sender.SenderId, msg.ReceiverType, msg.ReceiverId, util.FormatMessage(msg.MessageType, msg.MessageContent), msg.Seq)
  135. c.Seq = msg.Seq
  136. ack := pb.MessageACK{
  137. DeviceAck: msg.Seq,
  138. ReceiveTime: util.UnixMilliTime(time.Now()),
  139. }
  140. c.Output(pb.PackageType_PT_MESSAGE, output.RequestId, &ack)
  141. default:
  142. fmt.Println("switch other")
  143. }
  144. }