前言

在上一篇 spring boot + layim + t-io 文件上传、 监听用户状态的实现 中,已经介绍了两个小细节:用户的在离线状态和群人数的状态变化。今天的主要内容就是用户加好友的实现。

简介

加好友,大家用过qq都知道,无非是发起好友申请,对方收到消息通知,然后处理。不过,本篇只讲前半部分,消息通知的处理留到下一篇去讲。因为内容有点多,怕是一时半会消化不了。在介绍主体流程之前,先给大家介绍一下准备工作。

准备工作

首先,为了让数据更贴近实战,所以我用了比较“真实”的用户数据。结合fly模板,完善了用户中心头部的用户信息的数据绑定。数据绑定部分判断了是否已经是好友,来决定是否出现“加为好友”的按钮。示例如下,当用户自己看到自己的主页时,是这样的:

看到非好友的用户主页,是这样的:

绑定数据部分,简单给大家介绍一下,就是用thymleaf模板绑定。后台访问页面的时候,将 model 赋值即可。

/**

* 属性赋值

* */

private void setmodel(user user,model model){

long currentuserid = getuserid();

long visituserid = user.getid();

//是否是自己

boolean isself = currentuserid == visituserid;

//两个用户是否已经是好友

boolean isfriend = groupservice.isfriend(currentuserid,visituserid);

map usermap = new hashmap<>(8);

usermap.put("avatar",user.getavatar());

usermap.put("name",user.getusername());

usermap.put("addtime", timeutil.formatdate(user.getcreateat())+" 加入");

if(user.getsign()==null ||user.getsign().length()==0) {

usermap.put("sign", "");

}else {

usermap.put("sign", "(" + user.getsign() + ")");

}

usermap.put("uid",user.getid());

usermap.put("self",isself || isfriend);

model.addattribute("user",usermap);

}

然后页面上,将model中的数据取出来。

加为好友

ok,以上就是简单的准备工作。想了解详情代码的可以去文末的github地址去搜寻。

发起好友申请

我们先根据layim的业务分析。首先,要知道我们要加谁(toid)为好友。然后在加上一个备注(remark)。这些东西交给后台就ok了。为了避免连表查询,对于系统消息的存储我做了用户名和用户头像的冗余。表主要包含字段:用户id,用户头像,用户名,被申请用户id,申请时间,申请类型,备注,已读等其他属性。

所以,发起好友申请就很简单了。就是一个添加功能,前端传的就是被申请人用户id和申请备注,后端组织数据插入到数据库,代码如下:

/**

* 提交好友申请

* */

public jsonresult savefriendapply(long toid,string remark){

remark = htmlutils.htmlescape(remark);

contextuser user = shiroutil.getcurrentuser();

long userid = long.parselong(user.getuserid());

int record = applyrepository.countbytoidanduidandtypeandresult(toid,userid,applytype.friend,0);

if(record > 0){

return jsonresult.fail("已经申请过");

}

apply apply = new apply();

apply.settype(applytype.friend);

apply.settoid(toid);

apply.setremark(remark);

apply.setuid(userid);

apply.setavatar(user.getavatar());

apply.setname(user.getusername());

apply.setread(false);

apply.setresult(0);

return saveapply(apply);

}

ok,申请完了,下面我们要做啥?没错,通知对方,喂,我向你发送了申请,快快处理。在这里呢我遇到了一个问题。由于springboot程序占用端口 8080,而t-io占用端口8888,也就是说,如果我想在8080端口的业务中主动调用8888的服务推送,我不知道如何获取相应的channelcontext。不过经过询问作者之后,一句话解决了我的问题。

拿到 servergroupcontext ,问题迎刃而解。

在之前的程序启动的时候注册了 layimwebsocketstarter 这个bean。所以,在8080业务端如果能拿到它的话就没问题了。

得到 layimwebsocketstarter ,就能得到  servergroupcontext, 然后就能在服务端做主动推送了。

当然可能没有开发过这个东西,对于上文中的问题不是很理解,没关系,其实我就想说明,如果从服务端主动向客户端推送消息的话,使用servergroupcontext即可。

服务端主动推送

以下代码在  com.fyp.layim.im.common.util.pushutil 中

ok,接上文,我们按照步骤来。

第一步,获取 layimwebsocketstarter 。

/**

* 获取starter

*/

private static layimwebsocketstarter getstarter(){

return (layimwebsocketstarter)springutil.getbean("layimwebsocketstarter");

}

第二步,获取 servergroupcontext

private static servergroupcontext getservergroupcontext(){

return getstarter().getservergroupcontext();

}

第三步,获取 channelcontext。

/**

* 获取channelcontext

* */

private static channelcontext getchannelcontext(string toid) {

servergroupcontext context = getservergroupcontext();

//找到用户

channelcontext channelcontext = context.users.find(context, toid);

return channelcontext;

}

第四步,发射,这里的代码就和聊天中的那部分代码差不多了。核心部分就是,获取channelcontext,然后给他发送消息。如果不在线就不用管。

/**

* 服务端主动推送消息

* */

public static void pushapplymessage(string toid) {

logger.info("执行到了发送方法:pushapplymessage");

layimtoclientnoticemsgbody body = new layimtoclientnoticemsgbody();

channelcontext channelcontext = getchannelcontext(toid);

//先判断是否在线,再去查询数据库,减少查询次数

if (channelcontext != null && !channelcontext.isclosed()) {

int count = getapplyservice().getunreadmsgcount(long.parselong(toid));

body.setcount(count);

push(channelcontext, body);

}

}

/**

* 服务端主动推送消息

* */

private static void push(channelcontext channelcontext,object msg) {

try {

wsresponse response = bodyconvert.getinstance().converttotextresponse(msg);

aio.send(channelcontext, response);

}catch (ioexception ex){

}

}

现在推送已经搞定了,那么什么时候推送呢?由于这个系统消息的推送可以不用那么即时,于是我看了下,springboot里面有类似的事件机制,于是乎 applyevent 就诞生了。

public class applyevent extends applicationevent {

public applyevent(object source) {

super(source);

}

private long toid;

public long gettoid(){

return toid;

}

public applyevent(object source, long toid) {

super(source);

this.toid = toid;

}

}

在创建一个listener,监听事件。

public class applylistener implements applicationlistener {

private logger logger = loggerfactory.getlogger(applylistener.class);

@override

public void onapplicationevent(applyevent applyevent) {

new thread(){

public void run(){

long toid = applyevent.gettoid();

//这里就要调用上文中的推送了

pushutil.pushapplymessage(toid.tostring());

}

}.start();

}

}

不过我有个疑问,发现listener中执行的时候是同步的。后来加了@async 和@enableasync 也没用,于是我就用了new thread().start()实现异步,确保不影响主要申请流程。(这是个疑问,自己没搞明白的地方)

最后,别忘了在application启动的时候把listener加上。

public static void main(string[] args) {

springapplication springapplication = new springapplication(layimapplication.class);

/**

* 这里监听增加listener,listener才会触发

* applylistener 是监听好友申请的事件

* */

springapplication.addlisteners(new applylistener());

springapplication.run(args);

}

功能拼接

马上就要成功了,我们在把事件串起来,在好友申请成功之后,发布事件。

/**

* 好友申请

* */

@postmapping(value = "/apply-friend")

public jsonresult apply(@requestparam("toid") long toid,@requestparam("remark") string remark){

jsonresult result = applyservice.savefriendapply(toid, remark);

//申请成功,发布申请事件,通知 toid处理消息,如果不在线,不会进行处理

if(result.issuccess()){

applicationcontext.publishevent(new applyevent("apply",toid));

}

return result;

}

功能演示

讲了那么多,给大家看一下成品效果。(用户场景:安小鸟加皇上为好友,皇上接收消息并查看)

皇上收到消息,系统弹出左下角的小数字4。(调用 layim.msgbox(msgcount) 方法)

皇上点开消息盒子:

皇上收到了四位爱妃的申请,寝食难安,他会怎么处理呢?欲知后事如何,且听下回分解~~~

总结

本篇主要介绍了一个加好友的流程的实现。

好友申请按钮出不出现取决于用户是否为自己,是否已经是好友。(后端也要做验证)

t-io的服务端主动推送,如何调用。关键词: servergroupcontext

event的使用,除了applicationevent,还可以拓展其他类型,如消息队列,eventbus等。

各种细节处理,比如先判断对方是否在线,在去查询数据库。或者结合缓存等

由于是自己摸索,难免有代码繁杂混乱之处,

以上所述是小编给大家介绍的springboot+layim+t-io 实现好友申请通知流程,希望对大家有所帮助

希望与广大网友互动??

点此进行留言吧!

java.好友发送验证申请_SpringBoot+LayIM+t-io 实现好友申请通知流程相关推荐

  1. java.好友发送验证申请,微信怎样填写验证语可以提高微信加好友通过率?

    微信一个互联网沟通.分享信息.开通店铺的工具.平台,它与别的聊天工具最大的区别在于偏向于移动端而存在的,可以适合从儿童至老年人的交流工具. 微信做为网络沟通工具使用时,它支持:文字.图片.视频.语音. ...

  2. java实现好友添加_SpringBoot+LayIM+t-io 实现好友申请通知流程

    前言 在上一篇 Spring boot + LayIM + t-io 文件上传. 监听用户状态的实现 中,已经介绍了两个小细节:用户的在离线状态和群人数的状态变化.今天的主要内容就是用户加好友的实现. ...

  3. java实现语音发送,Java实现发送手机短信语音验证功能代码实例

    这篇文章主要介绍了java实现发送手机短信语音验证功能代码实例,www.cppcns.com文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 利用第三方 ...

  4. Java实现QQ邮箱验证激活 Java简单发送邮箱

    Java简单发送邮箱 1.首先要去qq邮箱 设置–账户–把所有服务都开启 (记住其中任意一个授权码就OK了) 如下图: 2. 导入jar包 创建测试类 (复制即可) 如下: package testE ...

  5. 使用java代码发送电子邮件

    开启SMTP服务 QQ邮箱----->设置------>账户 pom.xml: <!--javaMail--><dependency><groupId> ...

  6. java jwt 验证_教程:用Java创建和验证JWT

    java jwt 验证 "我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多 ...

  7. 教程:用Java创建和验证JWT

    "我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证. Java ...

  8. JAVA对接发送SMS短信服务

    JAVA对接发送SMS短信服务 短信服务申请 JAVA对接 代码编写 配置类 SmsComponent nacos配置中心--对应上面读取的参数 调用 Vue前端测试代码 效果 结语 短信服务申请 网 ...

  9. java实现发送qq邮箱验证码

    1.登录qq邮箱,开启POP3/SMTP服务 路径:qq邮箱--->设置---->选择账户----> 打开 按照要求发送短信后得到授权码 得到授权码后要记得点击确定,页面拉到最下方点 ...

  10. Java实现发送手机验证码,发送短信

    要发送短信,我们需要第三方提供的短信接口,这里我使用阿里云的短信服务. 首先进入阿里云的官网,然后注册.登陆之后选择云通信-->短信服务 然后点击免费开通. 开通后进入控制中心,选择右上方的支持 ...

最新文章

  1. 【组队学习】【29期】7. 集成学习(上)
  2. luogu P2596 [ZJOI2006]书架(平衡树、无旋treap(按排名分裂)一些更复杂的操作)
  3. github中SSH的Key
  4. Ubuntu常用终端快捷键
  5. ctrl+alt+T出来的终端窗口非常小
  6. cordova 一个将web应用程序封装成app的框架
  7. 计算机win7无法安装,新机装不了Win7?照这个方法5分钟搞定!
  8. 在debian上安装vmware tools的问题
  9. python如何下载pandas、时间延长_大pandas,python – 如何在时间表中选择具体时间
  10. 吴昊品游戏核心算法 Round 18 —— 吴昊教你玩Zen Puzzle Garden
  11. 51汇编与c语言混合编程,C51与汇编混合编程详解
  12. 如何使用Mac预览程序将png转换为jpg格式的技巧分享
  13. 2016年大数据发展趋势预测
  14. 雨夜赶长路,房企必经的三场“价值战事”
  15. Fatal signal 11 (SIGSEGV) at 0x00000014 (code=1), thread 29925 (cloud.diversion)
  16. App为了漂亮脸蛋也要美颜,Theme 与 Style 的使用,附一键变装 demo
  17. 异步爬取有道词典(入门js逆向)
  18. 著名歌唱家大衣哥太豪横了,参加商演被主办方请到五星级酒店就餐
  19. android开发apk捆绑,[原创]ApkAssist(Apk一键捆绑工具)
  20. Android笔记:Zing二维码扫描解决二维码被拉伸

热门文章

  1. Prism for WPF 搭建一个简单的模块化开发框架(一)
  2. 工厂设计模式-三种实现方式
  3. MongoDB之:Query使用积累(1)
  4. hbase 1.3.2 源码 IDEA编译执行
  5. 性能测试策略和指标的基本了解
  6. ScalersTalk成长会机器学习小组-深度学习第3次学习笔记
  7. Java毕设项目春运出行铁路路线规划推荐系统计算机(附源码+系统+数据库+LW)
  8. Creo集成之曲面生成JT
  9. IOS_CoreText的个人理解[高深精]
  10. Mybatis实例参考04-列名与属性名不一致的解决方法