这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天
视频Feed流
需求
在登录\非登录状态下,向用户推送发布时间倒序的视频。
基本流程
1.用户下划屏幕发出视频推流请求,后端接收请求,jwt鉴权并记录登录状态。
2.rpc调用VideoService进入video数据库进行查询,以request中的latest_time为基准,按照发布时间倒序返回最多30条视频信息。
3.根据每条视频信息所对应的user_id的集合,得到user_list之后rpc调用UserService,获得每个user_id对应的user结构体变量所包括的详细信息(比如粉丝数、点赞数等等)。
3.1在登录情况下,再rpc调用FavoriteService,判别当前用户与推流视频之间是否存在点赞关系并正确显示。
4.将这些信息进行组装,后端回复前端。
业务流程图
核心代码
/*
/cmd/video/service/feed_video.go
*/
type FeedVideoService struct {
ctx context.Context
}
func NewFeedVideoService(ctx context.Context) *FeedVideoService {
return &FeedVideoService{ctx: ctx}
}
func (f *FeedVideoService) FeedVideo(req *douyinvideo.DouyinFeedRequest) ([]*douyinvideo.Video, int64, error) {
res, err := db.QueryVideo(f.ctx, *req.LastestTime)
if err != nil {
fmt.Println("db.QueryVideo something wrong")
return nil, 0, err
}
if len(*res) == 0 {
return nil, time.Now().Unix(), nil
}
//记录视频最近发布时间的时间戳
respLatesttime := (*res)[len(*res)-1].PubTime
/*
1.从video数据库表中进行video相关记录的查询
2.根据返回的video_db类型数据调用其他rpc服务,得到相关数据。
3.将相关数据进行组装。
*/
userList := GetUserListFromVideoDb(res)
uid, err := strconv.ParseInt(*req.Token, 10, 64)
douyinvideoUserList, err := GetUserListForVideo(userList, uid)
newVideo := pack.VideoDbToVideoService(res, douyinvideoUserList, uid)
return newVideo, respLatesttime, nil
}
// GetUserListFromVideoDb 整合数据库中所包含的user_id
func GetUserListFromVideoDb(dbList *[]db.Video_db) *[]int64 {
var UserIdList []int64
for _, v := range *dbList {
UserIdList = append(UserIdList, int64(v.UserId))
}
return &UserIdList
}
// GetUserListForVideo 调用rpc服务,返回user_id对应的Author的结构体信息
func GetUserListForVideo(userIdList *[]int64, userid int64) ([]*douyinvideo.User, error) {
var UserModelList []*douyinvideo.User
//区分当前是否为登录状态
if userid != -1 {
for _, v := range *userIdList {
uUser, err := rpc.GerUser(context.Background(), &douyinuser.GetUserRequest{
UserId: userid,
ToUserId: v,
})
if err != nil {
return nil, err
}
user := pack.DyUserUserToDyVideoUser(uUser)
UserModelList = append(UserModelList, user)
}
return UserModelList, nil
} else {
for _, v := range *userIdList {
uUser, err := rpc.GerUser(context.Background(), &douyinuser.GetUserRequest{
UserId: v,
ToUserId: v,
})
if err != nil {
fmt.Println(err)
return nil, err
}
user := pack.DyUserUserToDyVideoUser(uUser)
UserModelList = append(UserModelList, user)
}
return UserModelList, nil
}
}
```
```