基于Gin + WebSocket + MongoDB 的IM即时聊天Demo(三)

296 阅读1分钟

「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」。

github地址:github.com/CocaineCong…

B站教程地址:www.bilibili.com/video/BV1BP…

2.3 写入

2.3.1 定义类型

我们定义的接受类型是json形式,结构体如下 我们这里设计了几个type

  • type = 1 接受消息

  • type = 2 获取历史消息

type SendMsg struct {
	Type    int `json:"type"`
	Content string `json:"content"`
}

2.3.2 读取数据

先用 PongHandler 返回当前的 socket 对象

	c.Socket.PongHandler()
	sendMsg := new(SendMsg)
	// _,msg,_:=c.Socket.ReadMessage() // 不是json格式用这个
	err := c.Socket.ReadJSON(&sendMsg)  // json格式就用这个

2.3.3 接受消息

如果传过来的type=1的话,那么我们就可以先去redis上面查询一下当前有多少人进行了连接。

	r1 ,_ := cache.RedisClient.Get(c.ID).Result()
	r2 ,_ := cache.RedisClient.Get(c.SendID).Result()

如果发了三条消息都没有回的话,就不可以再发了。防止消息轰炸。

	replyMsg := &ReplyMsg{
		Code:    e.WebsocketLimit,
		Content: "达到限制",
	}
	msg , _ := json.Marshal(replyMsg)
	_ = c.Socket.WriteMessage(websocket.TextMessage, msg)

如果没有的话,就先记录到redis中进行缓存

	cache.RedisClient.Incr(c.ID)
	_ , _ =cache.RedisClient.Expire(c.ID,time.Hour*24*30*3).Result()

之后,我们再进行广播消息

Manager.Broadcast <- &Broadcast{
	Client:c,
	Message:[]byte(sendMsg.Content),
}

2.3.3 获取历史消息

那这个时候我们传来的 type 就等于 2,Content就是时间戳

我们设置的话,是只保存三个月的,三个月过后我们就可以删除了。

	timeT, err := strconv.Atoi(sendMsg.Content) // 传送来时间
	if err != nil {
		timeT = 9999999
	}
	results, _ := FindManyMsg(conf.MongoDBName,c.SendID,c.ID,int64(timeT),10)

这个FindManyMsg后面再说 返回前十条

	if len(results) > 10 {
		results = results[:10]
	}else if len(results) == 0{
		replyMsg := &ReplyMsg{
			Code:e.WebsocketEnd,
			Content:"到底了",
	}

写入返回

	msg , _ := json.Marshal(replyMsg)
	_ = c.Socket.WriteMessage(websocket.TextMessage,msg)

2.4 读取

我们用一个for循环进行消息的读取。

如果有消息的话,就WriteMessage写下来。发送出去。

for{
    select {
    case message, ok := <-c.Send :
            if !ok {
                    _=c.Socket.WriteMessage(websocket.CloseMessage,[]byte{})
                    return
            }
            log.Println(c.ID,"接受消息:",string(message))
            replyMsg := &ReplyMsg{
                    Code:e.WebsocketSuccessMessage,
                    Content:fmt.Sprintf("%s",string(message)),
            }
            msg , _ := json.Marshal(replyMsg)
            _ = c.Socket.WriteMessage(websocket.TextMessage, msg)
    }
}