融云java服务器端--好友关系

官方提供的服务器端代码是用nodejs写的(地址https://github.com/sealtalk/sealtalk-server),我需要改成用spring-boot实现。

也是费了好大的功夫。

融云【单聊】的机制在于,只要知道 两个人的 id,就能互相发送消息,不管是不是好友,所以就需要 我们自己写的后台 来 限制下:不是好友就不能互相聊天。 

注意:如果用户 A  把 B 给删了,但在B 的app上还有对话窗口存在的话,此时按照融云的机制, B 还是可以和 A聊天的,这个时候 就需要使用【融云API】把 B 添加到 A 的【黑名单】里面,这样二者就无法通信了。

这里得废话一句:进入融云后台,右上角找到【我的控制台】点击进去

左下角找到【API调用】,先再这里面调试程序,能起到事半功倍的效果!!

一、数据库表rongcloud_friendship

CREATE TABLE `rongcloud_friendship` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` varchar(25) NOT NULL COMMENT '当前用户id',
  `friend_id` varchar(25) NOT NULL COMMENT '好友id',
  `display_name` varchar(32) DEFAULT '' COMMENT '备注名',
  `message` varchar(64) DEFAULT NULL COMMENT '加好友时的“请求信息”',
  `status` int(10) unsigned DEFAULT NULL COMMENT '10: 请求, 11: 被请求, 20: 同意, 21: 忽略, 30: 被删除',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `friendship_user_id_friend_id` (`user_id`,`friend_id`)
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8;

二、status定义

好友之间的关系

status

字段

说明

10

REQUESTING

请求

11

REQUESTED

被请求 

20

AGREED

同意

21

IGNORED

忽略

30

DELETED

被删除

一张图了解:

三、返回格式定义:

public class RongCloudResultDataObject<T> {
    /***错误代码**/
    private Integer code;
    /**消息**/
    private String msg;
    /**消息体**/
    private T result;
     
    /**此处是getter和setter*/
}

public class RongCloudResultUtil {
    public static RongCloudResultDataObject success(int code, String msg, Object object){
        RongCloudResultDataObject resultObject = new RongCloudResultDataObject();
        resultObject.setCode(code);
        resultObject.setMsg(msg);
        resultObject.setResult(object);
        return resultObject;
    }

    /**
     * 定义错误返回格式
     * @param code
     * @param msg
     * @return
     */
    public static RongCloudResultDataObject error(Integer code , String msg){
        RongCloudResultDataObject resultObject = new RongCloudResultDataObject();
        resultObject.setCode(code);
        resultObject.setMsg(msg);
        return resultObject;
    }
}

引入maven:

<dependency>
    <groupId>cn.rongcloud.im</groupId>
    <artifactId>server-sdk-java</artifactId>
    <version>3.0.1</version>
</dependency>

四、发送融云系统消息,单聊消息(这里主要是小灰条),封装成工具类

public class CommonUtil {
    /**你的key和secret*/
    public static final String appKey = "";
    public static final String appSecret = "";
    
    //默认空头像(用户)
    public static final String DEFAULT_IMAGE = "112.jpg";
    private static RongCloud rongCloud = RongCloud.getInstance(appKey,appSecret);
    /**
     * 通过融云发送系统信息,详见https://www.rongcloud.cn/docs/message_architecture.html#group_notification_message
     * @param senderId 发送人
     * @param targetIds 接收人(数组)
     * @param baseMessage 消息内容
     * @param pushContent 推送内容
     * @param pushData 推送数据
     */
    public static void sendSystemMessage(String senderId, String[] targetIds, BaseMessage baseMessage, String pushContent, String pushData){
        SystemMessage systemMessage = new SystemMessage()
                .setSenderId(senderId)
                .setTargetId(targetIds)
                .setObjectName(baseMessage.getType())
                .setContent(baseMessage)
                .setPushContent(pushContent)
                .setPushData(pushData)
                .setIsPersisted(0)
                .setIsCounted(0)
                .setContentAvailable(0);
        try {
            rongCloud.message.system.send(systemMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 通过融云发送单聊消息
     */
    public static void sendPrivateMsg(String senderId, String targetId, BaseMessage baseMessage){
        PrivateMessage privateMessage = new PrivateMessage()
                .setSenderId(senderId)
                .setTargetId(new String[]{targetId})
                .setObjectName(baseMessage.getType())
                .setContent(baseMessage)
                .setPushContent("")
                .setPushData("")
                .setCount("")
                .setVerifyBlacklist(0)
                .setIsPersisted(0)
                .setIsCounted(0)
                .setIsIncludeSender(0);
        //发送单聊方法
        try {
            rongCloud.message.msgPrivate.send(privateMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 移除黑名单
     */
    public static void removeBlackList(String userId,String friendId){
        UserModel user = getUserModel(userId,friendId);
        try {
            rongCloud.user.blackList.remove(user);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 添加黑名单
     */
    public static void addBlackList(String userId,String friendId){
        UserModel user = getUserModel(userId,friendId);
        try {
            rongCloud.user.blackList.add(user);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static UserModel getUserModel(String userId,String friendId){
        UserModel blackUser = new UserModel().setId(userId);
        UserModel[] blacklist = {blackUser};
        UserModel user = new UserModel()
                .setId(friendId)
                .setBlacklist(blacklist);
        return user;
    }
}

五、/invite 发起好友请求:(其实主要就是   判断 status 的值,再更改status的值 )

/**
 * @param userId 请求者
 * @param friendId 被请求者
 * @param message 请求者发出的“验证消息”
 * @param pushContent 推送
 * @param pushData 推送内容
 */
@PostMapping("/invite")
public RongCloudResultDataObject invite(@RequestBody Map<String,Object> map){
      if(map.get("userId") == null || map.get("friendId") == null){
        return RongCloudResultUtil.error(1001,"userId,friendId不能为null");
      }
      String userId = map.get("userId").toString(); //当前用户id
      String friendId = map.get("friendId").toString(); //要添加的好友id
      if(Objects.equals(userId, "") || Objects.equals(friendId, "")){
          return RongCloudResultUtil.error(1001,"userId,friendId必需有值");
      }

      String message = map.get("message") == null ? "我是 "+ userId : map.get("message").toString();//添加好友的验证信息 的默认值
      String pushContent = map.get("pushContent") == null ? "": map.get("pushContent").toString(); //推送
      String pushData = map.get("pushData") == null ? "" : map.get("pushData").toString();  //推送内容

      //该方法执行的sql语句是:select * from rongcloud_friendship where user_id = ?1 and friend_id = ?2
      //数据库有两条记录,查看这两个用户之间的关系
      //请求者
      FriendShip fg = friendShipService.findByUserIdAndFriendId(userId, friendId);
      //被请求者
      FriendShip fd = friendShipService.findByUserIdAndFriendId(friendId,userId);
      
      int fgStatus,fdStatus;
      String action = "Added";
      String resultMessage = "无需对方确认,已成功添加好友";

      //获得用户的昵称
      User user = userService.findByAccount(userId);
      String extra = "{sourceUserNickname:"+ user.getNickname() + ",version:123456}";

      //数据库没有这两条记录,说明是第一次添加(后面删掉好友的时候,仅仅是改变status的值)
      if(fg != null && fd != null){
         //status都为20表示已经是好友,无需再申请添加
         if(fg.getStatus() == AGREED && fd.getStatus() == AGREED){
             return RongCloudResultUtil.error(400, "你们已经是好友了");
         }
         if(fd.getStatus() == AGREED ||  fd.getStatus() == REQUESTING){
             fgStatus = REQUESTING;
             fdStatus = REQUESTED;
             action = "Sent";
             resultMessage = "请求已发送";
         }else if((fg.getStatus() == DELETED && fd.getStatus() == DELETED) || (fg.getStatus() == AGREED && fd.getStatus() == DELETED) || (fg.getStatus() == REQUESTING && fd.getStatus() == IGNORED) || (fg.getStatus() == REQUESTING && fd.getStatus() == REQUESTED)){
             fgStatus = REQUESTING;
             fdStatus = REQUESTED;
             action = "Sent";
             resultMessage = "请求已发送";
         }else{
             return msg(200, "什么都不做.","None");
         }
         //更新状态
         fg.setStatus(fgStatus);
         fd.setStatus(fdStatus);
         fd.setMessage(message);
         fg.setUpdateTime(new Date());
         fd.setUpdateTime(new Date());
         //这里执行的sql语句就是update语句
         friendShipService.update(fg);
         friendShipService.update(fd);

         //通过融云发送系统消息,提醒对方**请求添加您为好友
         if(fd.getStatus() == REQUESTED){     
         sendContactMessage(CONTACT_OPERATION_REQUEST,userId,friendId,message,pushContent
                     ,pushData,extra);
         }
         return RongCloudUtils.success(resultMessage,action);
      }else{
         //之前没有加过好友
         //更新请求者的 status为 requesting 10
         saveFriendShip(userId,friendId, "", REQUESTING);
         //更新被请求者的 status 为 requested 11
         saveFriendShip(friendId,userId,message,REQUESTED);
                
         sendContactMessage(CONTACT_OPERATION_REQUEST,userId,friendId,message,pushContent
                      ,pushData,extra);
             return msg(200, "请求已发送","Sent");
         }
     }
  }

  private void sendContactMessage(String contact,String senderId,String targetId,String message,String pushContent,String pushData,String extra){
        ContactNtfMessage contactNtfMessage = new ContactNtfMessage(contact,extra,senderId,targetId,message);
        CommonUtil.sendSystemMessage(senderId,new String[]{targetId},contactNtfMessage,pushContent,pushData);
    }

六、/agree 同意好友请求

主要在于小灰条,可查看 融云控制台里面的 API调用

    /**
     * 同意好友请求
     * @param userId 同意添加 friendId为好友
     */
    @PostMapping("/agree")
    public RongCloudResultDataObject agree(@RequestBody Map<String,Object> map){
        if(map.get("userId") == null || map.get("friendId") == null){
            return RongCloudResultUtil.error(1001,"userId,friendId不能为null");
        }
        String userId = map.get("userId").toString(); //当前用户id (被请求者)
        String friendId = map.get("friendId").toString(); //请求者
        if(Objects.equals(userId, "") || Objects.equals(friendId, "")){
            return RongCloudResultUtil.error(1001,"userId,friendId必需有值");
        }

        //更新双方的 status为  AGREE
        //该方法执行的sql语句是:select * from rongcloud_friendship where user_id = ?1 and friend_id = ?2
        FriendShip fg = friendShipService.findByUserIdAndFriendId(friendId,userId);
        FriendShip fd = friendShipService.findByUserIdAndFriendId(userId,friendId);
        if(fg.getStatus() != REQUESTING && fg.getStatus() != AGREED && fg.getStatus() != REQUESTED){
            return RongCloudResultUtil.error(404,"无效的好友请求,或者未知好友");
        }
        friendShipService.updateStatus(userId,friendId,AGREED,new Date(),"");
        friendShipService.updateStatus(friendId,userId,AGREED,new Date(),"");
        //给请求者 发一条消息说,我同意你的请求了
        User user = userService.findByAccount(userId);
        User friend = userService.findByAccount(friendId);
        String extra = "{sourceUserNickname:"+ user.getNickname() + ",version:123456}";
        sendContactMessage(CONTACT_OPERATION_ACCEPT_RESPONSE,userId,friendId,"我是"+userId+",我已经同意你的好友请求了","","",extra);
        //小灰条通知
        CommonUtil.sendPrivateMsg(userId,friendId,new InformationNtfMessage("你已添加了"+ friend.getNickname() +",现在可以开始聊天了。",""));
        //发送文本消息
        CommonUtil.sendPrivateMsg(userId,friendId,new TxtMessage("我通过了你的朋友验证请求,现在我们可以开始聊天了",""));
        CommonUtil.sendPrivateMsg(friendId,userId,new TxtMessage(fd.getMessage(),""));

        //移除黑名单
        CommonUtil.removeBlackList(userId,friendId);
        CommonUtil.removeBlackList(friendId,userId);

        return RongCloudResultUtil.success();
    }

例如:  【十月】请求添加【实话实说】为好友,发送的验证请求内容是“我是十月,通过下”。

【实话实说】同意请求。 此时,【十月】会给【实话实说】发一条  TxtMsg文本消息 (发送的内容就是 它请求的验证消息)

【实话实说】也会发一条消息给【十月】来通知对方我同意了请求(这里有小灰条)

七、/delete   删除好友

注意 只需要 将一方的 status 改为  30 就可以了,并且需要加入融云提供的黑名单,两人才不能通信(不然只要聊天界面还在,两人还是可以聊天的)!

    /**
     * 逻辑删除(修改status为30)
     * @param map
     * @return
     */
    @PostMapping("/delete")
    public RongCloudResultDataObject delete(@RequestBody Map<String,Object> map){
        if(map.get("userId") == null || map.get("friendId") == null){
            return RongCloudResultUtil.error(1001,"userId,friendId字段是必需的");
        }
        String userId = map.get("userId").toString(); //当前id
        String friendId = map.get("friendId").toString(); //好友id
        if(Objects.equals(userId, "") || Objects.equals(friendId, "")){
            return RongCloudResultUtil.error(1001,"userId,friendId必需有值");
        }

        FriendShip fg = friendShipService.findByUserIdAndFriendId(userId,friendId);
        if(fg == null || fg.getStatus() != AGREED){
            return RongCloudResultUtil.error(405,"你们不是好友关系,不能执行相关操作");
        }
        //把好友备注给清空下
        fg.setDisplayName("");
        fg.setMessage("");
        fg.setStatus(DELETED);
        fg.setUpdateTime(new Date());
        friendShipService.update(fg);

        //添加到黑名单
        CommonUtil.addBlackList(userId,friendId);
        CommonUtil.addBlackList(friendId,userId);
        return RongCloudResultUtil.success();
    }

其它方法不贴了,主要的难点在于,发送融云提供的系统消息,通知对方我要加你为好友了,以及小灰条~

猜你喜欢

转载自blog.csdn.net/why_su/article/details/83653961
今日推荐