「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」。
github地址:github.com/CocaineCong…
B站教程地址:www.bilibili.com/video/BV1BP…
2.5 插入与查询
2.5.1 插入数据
我们使用的是mongoDB进行消息的存储,MongoDB的插入非常简单,文档数据库,插入json格式即可。
- 定义一个存储的数据类型
type Trainer struct {
Content string `bson:"content"` // 内容
StartTime int64 `bson:"startTime"` // 创建时间
EndTime int64 `bson:"endTime"` // 过期时间
Read uint `bson:"read"` // 已读
}
- 传入数据库,用户ID,内容,是否已读,过期时间
func InsertMsg(database string, id string, content string, read uint, expire int64) (err error) {
collection := conf.MongoDBClient.Database(database).Collection(id)
comment := ws.Trainer{
Content: content,
StartTime: time.Now().Unix(),
EndTime: time.Now().Unix() + expire,
Read: read,
}
_, err = collection.InsertOne(context.TODO(),comment)
return
}
2.5.2 查询数据
MongoDB的查询也非常容易,按照json格式进行查询。
- 定义一个存储对象的切片
var resultsMe []ws.Trainer
- 通过用户id查询所有的用户消息
idCollection := conf.MongoDBClient.Database(database).Collection(id)
- 根据传入的
time定义一个过滤器,进行这个时间内的查询。
filter := bson.M{"startTime": bson.M{"$lt": time}}
- 根据
filter进行查询,然后再通过时间进行倒序排序,并且限定页数。
sendIdTimeCursor, err := sendIdCollection.Find(context.TODO(), filter,
options.Find().SetSort(bson.D{{"StartTime", -1}}), options.Find().
SetLimit(int64(pageSize)))
- 把数据查询数据传入到resultsMe中
err = idTimeCurcor.All(context.TODO(), &resultsMe)
2.6 对方不在线
- 广播信息
case broadcast := <-Manager.Broadcast:
message := broadcast.Message
sendId := broadcast.Client.SendID
flag := false // 默认对方不在线
- 如果没有这个人的话就一直找就可以了
for id, conn := range Manager.Clients {
if id != sendId {
continue
}
select {
case conn.Send <- message:
flag = true
default:
close(conn.Send)
delete(Manager.Clients, conn.ID)
}
}
- 还是找到的话
就可以当作已读信息,存储
if flag {
log.Println("对方在线应答")
replyMsg := &ReplyMsg{
Code: e.WebsocketOnlineReply,
Content: "对方在线应答",
}
msg , err := json.Marshal(replyMsg)
_ = broadcast.Client.Socket.WriteMessage(websocket.TextMessage, msg)
err = InsertMsg(conf.MongoDBName, id, string(message), 1, int64(3*month))
if err != nil {
fmt.Println("InsertOneMsg Err", err)
}
}
- 如果没有找到的话,就是未读消息了。
else {
log.Println("对方不在线")
replyMsg := ReplyMsg{
Code: e.WebsocketOfflineReply,
Content: "对方不在线应答",
}
msg , err := json.Marshal(replyMsg)
_ = broadcast.Client.Socket.WriteMessage(websocket.TextMessage, msg)
err = InsertMsg(conf.MongoDBName, id, string(message), 0, int64(3*month))
if err != nil {
fmt.Println("InsertOneMsg Err", err)
}
}
3. 演示
- 测试http连接
- 进行ws连接,连接服务器
- 当id=1上线,但是id=2没上线的时候发送消息
- 当id=2上线之后
- 再次发消息,就是在线应答了
- 这边就实时接受到消息了
- 获取历史信息
4. 源码地址
github地址