1. 好友关注

在探店图文的详情页面中,可以关注发布笔记的作者:

进到探店笔记详情页,会发出两个请求,1是判断是否已经关注,2是尝试关注用户的请求。

关注是User之间的关系,是博主与粉丝的关系,数据库中有一张tb_follow表来标示:

其中userId是当前登录的用户id,follow_user_id是被关注的用户id

实现对应接口:

1. 判断是否关注:

Controller层:

@GetMapping("/or/not/{id}")
public Result isFollow(@PathVariable("id") Long followUserId) {return followService.isFollow(followUserId);
}

Service层:

@Override
public Result isFollow(Long followUserId) {// 1.获取登录用户Long userId = UserHolder.getUser().getId();// 2.查询是否关注 select count(*) from tb_follow where user_id = ? and follow_user_id = ?Integer count = query().eq("user_id", userId).eq("follow_user_id", followUserId).count();// 3.判断return Result.ok(count > 0);}

2. 关注业务接口:如果已经关注,就在数据库中添加userid(当前登录用户的id)和关注的用户id(follow_user_id)等数据。

如果未关注,就删除数据。

Controller层:

//关注
@PutMapping("/{id}/{isFollow}")
public Result follow(@PathVariable("id") Long followUserId, @PathVariable("isFollow") Boolean isFollow) {return followService.follow(followUserId, isFollow);
}

Service层:

关注service@Overridepublic Result follow(Long followUserId, Boolean isFollow) {// 1.获取登录用户Long userId = UserHolder.getUser().getId();// 1.判断到底是关注还是取关if (isFollow) {// 2.关注,新增数据Follow follow = new Follow();follow.setUserId(userId);follow.setFollowUserId(followUserId);boolean isSuccess = save(follow);} else {// 3.取关,删除 delete from tb_follow where user_id = ? and follow_user_id = ?remove(new QueryWrapper<Follow>().eq("user_id", userId).eq("follow_user_id", followUserId));}return Result.ok();}

2. 好友共同关注

需求:利用Redis中恰当的数据结构,实现共同关注功能。在博主个人页面展示出当前用户与博主的共同关注呢。

我们可以使用Redis中的set集合,将每个用户关注的用户id,也就是follow_user_id,存入set集合中,每个用户对应一个关注博主的set集合,然后取他们之间的交集,就可以找到共同关注的博主。

所以,我们要先改造之前关注用户的业务逻辑,每次用户关注时,将关注的用户存入Set集合中。

关注业务改造:

@Override
public Result follow(Long followUserId, Boolean isFollow) {// 1.获取登录用户Long userId = UserHolder.getUser().getId();String key = "follows:" + userId;// 1.判断到底是关注还是取关if (isFollow) {// 2.关注,新增数据Follow follow = new Follow();follow.setUserId(userId);follow.setFollowUserId(followUserId);boolean isSuccess = save(follow);if (isSuccess) {// 把关注用户的id,放入redis的set集合 sadd userId followerUserIdstringRedisTemplate.opsForSet().add(key, followUserId.toString());}} else {// 3.取关,删除 delete from tb_follow where user_id = ? and follow_user_id = ?boolean isSuccess = remove(new QueryWrapper<Follow>().eq("user_id", userId).eq("follow_user_id", followUserId));if (isSuccess) {// 把关注用户的id从Redis集合中移除stringRedisTemplate.opsForSet().remove(key, followUserId.toString());}}return Result.ok();
}

然后,我们就可以实现共同关注的接口了。

Controller层:

@GetMapping("/common/{id}")public Result followCommons(@PathVariable("id") Long followUserId){return followService.followCommons(followUserId);}

Service层:

1.获取当前用户id和目标用户id在redis中的key

2.使用set中求交集的方法,得到结果

3.解析结果,得到id组合

4.通过id组合获取用户组合。

5.返回用户组合给前端。

@Override
public Result followCommons(Long id) {// 1.获取当前用户Long userId = UserHolder.getUser().getId();String key = "follows:" + userId;// 2.求交集String key2 = "follows:" + id;Set<String> intersect = stringRedisTemplate.opsForSet().intersect(key, key2);if (intersect == null || intersect.isEmpty()) {// 无交集return Result.ok(Collections.emptyList());}// 3.解析id集合List<Long> ids = intersect.stream().map(Long::valueOf).collect(Collectors.toList());// 4.查询用户List<UserDTO> users = userService.listByIds(ids).stream().map(user -> BeanUtil.copyProperties(user, UserDTO.class)).collect(Collectors.toList());return Result.ok(users);
}

共同关注功能实现。

3. 关注推送(Feed流)

关注推送也叫做Feed流,直译为投喂。为用户持续的提供“沉浸式”的体验,通过无限下拉刷新获取新的信息。

传统的推送模式是用户自己查找内容,而Feed这是根据内容信息来取查找对应用户并推送

Feed流产品有两种常见模式:

Timeline:不做内容筛选,简单的按照内容发布时间排序,常用于好友或关注。例如朋友圈

  • 优点:信息全面,不会有缺失。并且实现也相对简单

  • 缺点:信息噪音较多,用户不一定感兴趣,内容获取效率低

智能排序:利用智能算法屏蔽掉违规的、用户不感兴趣的内容。推送用户感兴趣信息来吸引用户

  • 优点:投喂用户感兴趣信息,用户粘度很高,容易沉迷

  • 缺点:如果算法不精准,可能起到反作用

这里我们的关注推送,就采用第一种 Timeline。

该模式的实现方法同样有三种:

1. 拉模式

也叫做读扩散。它是每个博主发出博客信息后,都有一个发件箱,这个时候,粉丝要来读它的信息,就从这个发件箱里拉取信息到自己的收件箱中并读取,所以叫拉模式。

缺点:可能会有延迟

2.推模式

也叫作写扩散。它是一个博主发布博客信息后,直接将博客推送到粉丝的收件箱中。这种方法,解决了拉模式的延迟问题,但也会导致内存问题。

3.推拉结合

也叫做读写混合,兼具推和拉两种模式的优点。

现在有三个粉丝,同时关注了大V博主,有两个粉丝关注了普通博主张三。

这时候,张三发送了博客信息,但由于它是普通博主,粉丝基数不大,不用担心内存问题,所以直接采用推模式,发送给粉丝。

而对于大V博主来说,将粉丝分为活跃粉丝和普通粉丝,活跃粉丝采用推模式,而普通粉丝采用拉模式,将消息放进收件箱中。

这就是三种实现模式,我们做个对比。

这里,我们采用推模式来实现好友推送功能。

这里提一嘴分页问题:

Feed流中的数据会不断更新,所以数据的角标也在变化,因此不能采用传统的分页模式

传统分页模式:

所以,我们必须采用Feed流的滚动分页。

1. 首先,修改新增探店笔记的业务,在保存blog到数据库的同时,推送到粉丝的收件箱

    @Overridepublic Result saveBlog(Blog blog) {// 获取登录用户UserDTO user = UserHolder.getUser();blog.setUserId(user.getId());// 保存探店博文boolean isSuccess = save(blog);if (!isSuccess){//没有保存成功,返回错误信息return Result.fail("新增失败!");}//成功,将博客信息放到粉丝收件箱//1.先获取粉丝群体 select * from tb_follow where follow_user_id = ?QueryChainWrapper<Follow> follows = followService.query().eq("follow_user_id", user.getId());//2.将消息推送至粉丝收件箱String key = "feeds:"+user.getId();stringRedisTemplate.opsForZSet().add(key,blog.getId().toString(),System.currentTimeMillis());// 返回idreturn Result.ok(blog.getId());}

Redis——好友关注、共同关注、Feed流推送相关推荐

  1. springboot完成拉取微信公众号关注列表并通过列表推送消息

    微信开放文档 微信小程序和公众号中,同一个用户在不同的应用中的openId是不同的,也就是说同一个用户在一个小程序和对应的公众号上是无法通过openId对应的,需要用微信唯一的unionId进行对应, ...

  2. 【虚幻引擎】UE4像素流推送PixelStreaming

    一.前言 虚幻引擎像素流送(Pixel Streaming)允许你从任何有屏幕的联网设备(例如计算机,手机,平板电脑等)播放虚幻项目.在这个教程里,我们将学习如何激活虚幻引擎的像素流送并从任何Web浏 ...

  3. 将h.264裸码流推送到RTMP服务器

    h.264裸码流的格式,参考"H.264-AVC-ISO_IEC_14496-10.pdf, page 211.",这个文档的下载地址:https://github.com/win ...

  4. 【已解决】Java 项目中利用 Redis 配合 Lua 脚本对短信推送消息做推送限制

  5. Redis实现朋友圈,微博等Feed流功能,实现Feed流微服务(业务场景、实现思路和环境搭建)

    文章目录 业务场景 Feed流相关概念 Feed流特征 Feed流分类 实现思路 环境搭建 数据库表结构 新建Feeds功能微服务ms-feeds 配置类 RedisTemplateConfigura ...

  6. 走进微信公众号实现关注之后推送一条服务器自定义的消息给用户

    下面是tp3.2实现的代码: <?php namespace Home\Controller; use Think\Controller; class IndexController exten ...

  7. 微信公众号开发(一)--公众号关注推送

    用户关注公众号回调 参考资料 微信公众平台 微信公众号开发文档 基本信息 AppID:开发者ID,微信公众号的唯一标识 AppSecret:开发者密码,操作微信公众号的验证 IP白名单:获取acces ...

  8. feed流和瀑布流_基础知识讲解:什么是feed流?(图文)

    feed是将用户主动订阅的若干消息源组合在一起形成内容聚合器,帮助用户持续地获取最新的订阅源内容.feed流即持续更新并呈现给用户内容的信息流. 最近常听朋友说中了抖音的毒,一有时间就刷抖音,根本停不 ...

  9. feed流和瀑布流_基础知识讲解:什么是feed流?

    feed是将用户主动订阅的若干消息源组合在一起形成内容聚合器,帮助用户持续地获取最新的订阅源内容.feed流即持续更新并呈现给用户内容的信息流. 最近常听朋友说中了抖音的毒,一有时间就刷抖音,根本停不 ...

最新文章

  1. 无人驾驶还有多久才能全面推开?
  2. 建环计算机应用试题,环境建环和给水排水工程计算机应用教材内容
  3. 小巧数据库 Derby 使用攻略
  4. .htaccess:正则表达式、重定向代码
  5. [Apple开发者帐户帮助]二、管理你的团队(6)找到您的团队ID
  6. stm32串口传输数据第一个数据被吞_stm32串口发送数据复位 第一个数据丢失
  7. OpenCV处理引起光学错觉的图像
  8. PHP一个比较完善的树形结构代码
  9. 微服务架构的常见问题
  10. 前端学习(2400):关于aixos的create方法
  11. 使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)——第1部分
  12. 最大隶属度原则_商圈广告精准投放,请牢记这四大黄金原则!
  13. centos mysql无法登录,解决centos下MySQL登录1045问题
  14. 幻方矩阵(魔方矩阵)
  15. LCP 03 机器人大冒险(分析-计算运动周期)
  16. 小程序 - 微信授权登录 微信授权绑定手机号
  17. 如何设置word的默认输入法——搜狗输入法
  18. Python中NaN、nan和NAN的区别及使用方法
  19. 必读的AI和深度学习博客
  20. 原 the app referencesnon-public selectors in payload

热门文章

  1. 【新星计划】如何写好你的博客,涨粉技巧总结
  2. 招投标概念及注意事项
  3. CC2591和RFX2401C在zstack中的设置
  4. Redis——5种数据结构底层实现原理
  5. iOS开发基础之第三方调起自己的App
  6. 第四章 WEB表单(二)
  7. 2014年7月份第2周51Aspx源码发布详情
  8. golang 基于文件的消息队列 ---> diskqueue
  9. 【Web技术】1159- 浅析 Web 录屏技术方案与实现
  10. python计算营业额代码_python计算营业额的代码_python 统计代码行数简单实例