媒介

  接上一版,这一版的页面与功用都有所优化,详细以下:

  1、优化登录阻拦

  2、登录后猎取一切挚友并辨别显现在线、离线挚友,挚友上线、下线都有符号

  3、将前后端交互的值改成用户id、显现值改成昵称nickName

  4、谈天音讯存储,点击挚友谈天,先追加谈天记录

  5、登录后猎取一切未读音讯并以小圆点的情势展现

  6、搜刮挚友、增加挚友

 

  优化细节

    1、登录阻拦由之前的经由过程途径中猎取账号,推断WebSocketServer.loginList中是不是存在key改成登录的时刻设置cookie,登录阻拦从cookie中取值

  登录、登出的时刻设置、删除cookie,


    /*** 登录*/@PostMapping("login")public Result<ImsUserVo>login(ImsUserVo userVo, HttpServletResponse response) {//加密后再去对照密文
userVo.setPassword(MD5Util.getMD5(userVo.getPassword()));
Result
<List<ImsUserVo>> result =list(userVo);if (result.isFlag() && result.getData().size() > 0) {
ImsUserVo imsUserVo
= result.getData().get(0);//置空隐私信息 imsUserVo.setPassword(null);//add WebSocketServer.loginList WebSocketServer.loginList.put(imsUserVo.getUserName(), imsUserVo);//设置cookie Cookie cookie = new Cookie("imsLoginToken", imsUserVo.getUserName());
cookie.setMaxAge(
60 * 30);//设置域//cookie.setDomain("huanzi.cn");//设置接见途径 cookie.setPath("/");
response.addCookie(cookie);
returnResult.of(imsUserVo);
}
else{return Result.of(null, false, "账号或暗码毛病!");
}
}
/*** 登出*/@RequestMapping("logout/{username}")publicModelAndView loginOut(HttpServletResponse response, @PathVariable String username) {newWebSocketServer().deleteUserByUsername(username,response);return new ModelAndView("login.html");
}

ImsUserController.java

  改成封闭websocket时不做操纵,仅减减socket衔接数


    /*** 衔接封闭挪用的要领*/@OnClosepublic voidonClose(Session session) {//下线用户名
        String logoutUserName = "";//从webSocketMap删除下线用户
        for (Entry<String, Session>entry : sessionMap.entrySet()) {if (entry.getValue() ==session) {
sessionMap.remove(entry.getKey());
logoutUserName
=entry.getKey();break;
}
}
deleteUserByUsername(logoutUserName,
null);
}
/**用户下线*/ public voiddeleteUserByUsername(String username, HttpServletResponse response){//在线人数减减 WebSocketServer.onlineCount--;if(WebSocketServer.onlineCount <= 0){
WebSocketServer.onlineCount
= 0;
}
if(StringUtils.isEmpty(response)){return;
}
//用户鸠合delete WebSocketServer.loginList.remove(username);//删除cookie 思绪就是替代本来的cookie,并设置它的生计时候为0//设置cookie Cookie cookie = new Cookie("imsLoginToken", username);
cookie.setMaxAge(
0);//设置域//cookie.setDomain("huanzi.cn");//设置接见途径 cookie.setPath("/");
response.addCookie(cookie);
//关照除本身以外的一切人 sendOnlineCount(username, "{'type':'onlineCount','onlineCount':" + WebSocketServer.onlineCount + ",username:'" + username + "'}");
}

WebSocketServer.java

  在登录阻拦器中从cookie取用户账户


        //其实存的是用户账号
        String imsLoginToken = "";
Cookie[] cookies
=request.getCookies();if (null !=cookies) {for(Cookie cookie : cookies) {if ("imsLoginToken".equals(cookie.getName())) {
imsLoginToken
=cookie.getValue();
}
}
}
if(WebSocketServer.loginList.containsKey(imsLoginToken)){//一般处置惩罚要求 filterChain.doFilter(servletRequest, servletResponse);
}
else{//重定向登录页面 response.sendRedirect("/imsUser/loginPage.html");
}

LoginFilter.java

  

  2、登录以后的用户列表不再是显现websocket衔接的用户,而是登录用户的挚友,同时要辨别显现挚友的在线与离线,以是新增一个猎取在线挚友的接口


    /*** 猎取在线挚友*/@PostMapping("getOnlineList")private Result<List<ImsUserVo>>getOnlineList(ImsFriendVo imsFriendVo) {returnimsFriendService.getOnlineList(imsFriendVo);
}
/*** 猎取在线挚友*/@Overridepublic Result<List<ImsUserVo>>getOnlineList(ImsFriendVo imsFriendVo) {//挚友列表 List<ImsFriendVo> friendList =list(imsFriendVo).getData();//在线挚友列表 ArrayList<ImsUserVo> onlineFriendList = new ArrayList<>();//遍历friendList for(ImsFriendVo imsFriendVo1 : friendList){
ImsUserVo imsUserVo
=imsFriendVo1.getUser();if (!StringUtils.isEmpty(WebSocketServer.getSessionMap().get(imsUserVo.getId().toString()))) {
onlineFriendList.add(imsUserVo);
}
}
returnResult.of(onlineFriendList);
}

ImsFriend

//衔接胜利竖立的回调要领
websocket.onopen = function() {//猎取挚友列表
    //$.post(ctx + "/imsFriend/list",{userId: username},function (data) {
    //console.log(data)
    //});
$.ajax({
type:
'post',
url: ctx
+ "/imsFriend/list",
contentType:
'application/x-www-form-urlencoded; charset=UTF-8',
dataType:
'json',
data: {userId: user.id},
success:
function(data) {if(data.flag) {//列表 let friends =data.data;for (let i = 0; i < friends.length; i++) {
let friend
=friends[i].user;
let $friendGroupList
= $("<div class=\"hz-group-list\">" + "<img class='left' style='width: 23px;' src='https://avatars3.githubusercontent.com/u/31408183?s=40&v=4'/>" + "<span class='hz-group-list-username'>" + friend.nickName + "</span><span id=\"" + friend.id + "-status\" style='color: #9c0c0c;;'>[离线]</span>" + "<div id=\"hz-badge-" + friend.id + "\" class='hz-badge'>0</div>" + "</div>");
$friendGroupList.user
=friend;
$(
"#hz-group-body").append($friendGroupList);
}
//挚友人数 $("#friendCount").text(friends.length);

getOnlineList(user.id);
}
},
error:
function(xhr, status, error) {
console.log(
"ajax毛病!");
}
});
};
/**
* 猎取在线挚友
*/ functiongetOnlineList(userId){
$.ajax({
type:
'post',
url: ctx
+ "/imsFriend/getOnlineList",
contentType:
'application/x-www-form-urlencoded; charset=UTF-8',
dataType:
'json',
data: {userId: userId},
success:
function(data) {if(data.flag) {//列表 let onlineFriends =data.data;for (let i = 0; i < onlineFriends.length; i++) {
let friend
=onlineFriends[i];
$(
"#" + friend.id + "-status").text("[在线]");
$(
"#" + friend.id + "-status").css("color", "#497b0f");
}
//挚友人数 $("#onlineCount").text(onlineFriends.length);
}
},
error:
function(xhr, status, error) {
console.log(
"ajax毛病!");
}
});
}

socketChart.js

 

  3、将之前前后端通报用户账户username改成用户id,同时,显现的是nickName昵称,修正的处所比较多,我就不贴代码了

 

   4、音讯存储 

   后端存储症结代码


    /*** 服务器接收到客户端音讯时挪用的要领*/@OnMessagepublic voidonMessage(String message, Session session) {try{//JSON字符串转 HashMap
            HashMap hashMap = new ObjectMapper().readValue(message, HashMap.class);//音讯范例
            String type = (String) hashMap.get("type");//泉源用户
            Map srcUser = (Map) hashMap.get("srcUser");//目的用户
            Map tarUser = (Map) hashMap.get("tarUser");//若是点击的是本身,那就是群聊
            if (srcUser.get("userId").equals(tarUser.get("userId"))) {//群聊
groupChat(session,hashMap);
}
else{//私聊 privateChat(session, tarUser, hashMap);
}
//后期要做音讯耐久化 ImsFriendMessageVo imsFriendMessageVo = newImsFriendMessageVo();
imsFriendMessageVo.setToUserId((Integer) tarUser.get(
"userId"));
imsFriendMessageVo.setFromUserId((Integer) srcUser.get(
"userId"));//谈天内容 imsFriendMessageVo.setContent(hashMap.get("message").toString());try{
SimpleDateFormat simpleDateFormat
= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
imsFriendMessageVo.setCreatedTime(simpleDateFormat.parse(hashMap.get(
"date").toString()));
imsFriendMessageVo.setUpdataTime(simpleDateFormat.parse(hashMap.get(
"date").toString()));
}
catch(ParseException e) {
e.printStackTrace();
}
imsFriendMessageService.save(imsFriendMessageVo);

}
catch(IOException e) {
e.printStackTrace();
}
}

WebSocketServer.java

  前端点击挚友时,猎取谈天记录症结代码


    //读取谈天记录
    $.post(ctx + "/imsFriendMessage/getChattingRecords", {
fromUserId: userId,
toUserId: toUserId
},
function(data) {if(data.flag) {for (let i = 0; i < data.data.length; i++) {
let msgObj
=data.data[i];//当谈天窗口与msgUserName的人雷同,笔墨在左侧(对方/其他人),否则在右侧(本身) if (msgObj.fromUserId ===userId) {//追加谈天数据 setMessageInnerHTML({
id: msgObj.id,
isRead: msgObj.isRead,
toUserId: msgObj.toUserId,
fromUserId: msgObj.fromUserId,
message: msgObj.content,
date: msgObj.createdTime
});
}
else{//追加谈天数据 setMessageInnerHTML({
id: msgObj.id,
isRead: msgObj.isRead,
toUserId: msgObj.fromUserId,
message: msgObj.content,
date: msgObj.createdTime
});
}
}
}
});

socketChart.js

    /*** 猎取A-B的谈天记录*/@RequestMapping("getChattingRecords")public Result<List<ImsFriendMessageVo>>getChattingRecords(ImsFriendMessageVo imsFriendMessageVo){returnimsFriendMessageService.getChattingRecords(imsFriendMessageVo);
}

@Override
public Result<List<ImsFriendMessageVo>>getChattingRecords(ImsFriendMessageVo imsFriendMessageVo) {//A对B的谈天记录 List<ImsFriendMessageVo> allList = new ArrayList<>(super.list(imsFriendMessageVo).getData());
Integer fromUserId
=imsFriendMessageVo.getFromUserId();
imsFriendMessageVo.setFromUserId(imsFriendMessageVo.getToUserId());
imsFriendMessageVo.setToUserId(fromUserId);
//B对A的谈天记录 allList.addAll(super.list(imsFriendMessageVo).getData());//默许按时候排序 allList.sort(Comparator.comparingLong(vo ->vo.getCreatedTime().getTime()));returnResult.of(allList);
}

ImsFriendMessage

 

 

  5、登录后猎取一切未读音讯并以小圆点的情势展现

  登录胜利后猎取与挚友的未读音讯症结代码,在猎取挚友列表以后挪用


                //猎取未读音讯
                $.post(ctx + "/imsFriendMessage/list",{toUserId:userId,isRead:0},function(data){if(data.flag){
let friends
={};//将fromUser兼并 for (let i = 0; i < data.data.length; i++) {
let fromUser
=data.data[i];if(!friends[fromUser.fromUserId]){
friends[fromUser.fromUserId]
={};
friends[fromUser.fromUserId].count
= 1;
}
else{
friends[fromUser.fromUserId].count
= friends[fromUser.fromUserId].count + 1;
}
}
for (let key infriends) {
let fromUser
=friends[key];//小圆点++ $("#hz-badge-" +key).text(fromUser.count);
$(
"#hz-badge-" + key).css("opacity", "1");
}
}
});

socketChart.js

 

  6、搜刮挚友、增加挚友

  可依照账号、昵称举行搜刮,个中账号是等值查询,昵称是隐约查询

  症结代码


//搜刮挚友
functionfindUserByUserNameOrNickName() {
let userNameOrNickName
= $("#userNameOrNickName").val();if (!userNameOrNickName) {
tip.msg(
"账号/昵称不能为空");return;
}

$.post(ctx
+ "/imsUser/findUserByUserNameOrNickName", {
userName: userNameOrNickName,
nickName: userNameOrNickName,
},
function(data) {if(data.flag) {
$(
"#friendList").empty();for (let i = 0; i < data.data.length; i++) {
let user
=data.data[i];
let $userDiv
= $("<div>" + "<img style='width: 23px;margin: 0 5px 0 0;' src='" + user.avatar + "'/>" + "<span>" + user.nickName + "(" + user.userName + ")</span>" + "<button onclick='tipUserInfo($(this).parent()[0].user)'>用户概况</button>" + "<button onclick=''>加挚友</button>" + "</div>");
$userDiv[
0].user =user;
$(
"#friendList").append($userDiv);
}
}
});
}

socketChart.js

    /*** 依据账号或昵称(隐约查询)查询*/@PostMapping("findUserByUserNameOrNickName")public Result<List<ImsUserVo>>findUserByUserNameOrNickName(ImsUserVo userVo) {returnimsUserService.findUserByUserNameOrNickName(userVo);
}


@Override
public Result<List<ImsUserVo>>findUserByUserNameOrNickName(ImsUserVo userVo) {return Result.of(CopyUtil.copyList(imsUserRepository.findUserByUserNameOrNickName(userVo.getUserName(), userVo.getNickName()), ImsUserVo.class));
}


@Query(value
= "select * from ims_user where user_name = :userName or nick_name like %:nickName%",nativeQuery = true)
List
<ImsUser> findUserByUserNameOrNickName(@Param("userName") String userName,@Param("nickName") String nickName);

ImsUser

   增加挚友

  首先要修正ims_friend构造,SQL以下,增加了一个字段is_agree,是不是已赞同挚友请求 0已请求但未赞同 1赞同 -1谢绝,之前查询挚友列表的post要求则须要新增参数isAgree=1


/*Navicat Premium Data Transfer

Source Server : localhost
Source Server Type : MySQL
Source Server Version : 50528
Source Host : localhost:3306
Source Schema : test

Target Server Type : MySQL
Target Server Version : 50528
File Encoding : 65001

Date: 14/05/2019 17:25:35
*/ SETNAMES utf8mb4;SET FOREIGN_KEY_CHECKS = 0;--------------------------------Table structure for ims_friend------------------------------ DROP TABLE IF EXISTS`ims_friend`;CREATE TABLE`ims_friend` (
`id`
int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`
user_id` int(11) NULL DEFAULT NULL COMMENT '用户id',
`friend_id`
int(11) NULL DEFAULT NULL COMMENT '挚友id',
`friend_type`
int(11) NULL DEFAULT NULL COMMENT '挚友分组id',
`friend_remark`
varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '挚友备注',
`is_agree`
int(1) NULL DEFAULT NULL COMMENT '是不是已赞同挚友请求 0已请求但未赞同 1赞同 -1谢绝',
`created_time`
datetime NULL DEFAULT NULL COMMENT '建立时候',
`updata_time`
datetime NULL DEFAULT NULL COMMENT '更新时候',PRIMARY KEY(`id`) USING BTREE
) ENGINE
= InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '挚友表' ROW_FORMAT =Compact;SET FOREIGN_KEY_CHECKS = 1;

View Code

  在工具栏新加一个体系音讯,贴出对应症结代码


//监听单击体系音讯,弹出窗口
$("body").on("click", "#sysNotification", function() {//此处为单击事宜要实行的代码
    if ($(".sysNotification").length <= 0) {
tip.dialog({
title:
"体系音讯",
class:
"sysNotification",
content:
"<div></div>",
shade:
0});
}
else{
$(
".sysNotification").click();
}
$(
"#sysNotification").find(".hz-badge").css("opacity",0);
$(
"#sysNotification").find(".hz-badge").text(0);//已谢绝 //请求挚友 $.post(ctx + "/imsFriend/list", {
friendId: userId,
isAgree:
0,
},
function(data) {if(data.flag) {for (let i = 0; i < data.data.length; i++) {
let user
=data.data[i].user;
let $userDiv
= $("<div>" + "<img style='width: 23px;margin: 0 5px 0 0;' src='" + user.avatar + "'/>" + "<span>" + user.nickName + "(" + user.userName + ")</span> 请求增加挚友<br/>" + "<button onclick='tipUserInfo($(this).parent()[0].user)'>用户概况</button>" + "<button onclick='agreeAddFriend(" + data.data[i].id + ")'>赞同</button>" + "</div>");
$userDiv[
0].user =user;
$(
".sysNotification .tip-content").append($userDiv);
}
}
});
});
//请求增加挚友 functionapplyToAddFriend(friendUserId) {
let nowTime
=commonUtil.getNowTime();
$.post(ctx
+ "/imsFriend/save", {
userId: userId,
friendId: friendUserId,
friendType:
1,
friendRemark:
"",
isAgree:
0,
createdTime: nowTime,
updataTime: nowTime,
},
function(data) {if(data.flag) {
tip.msg({text:
"已为你递交挚友请求,对方赞同好便可成为挚友!",time:3000});
}
});
}
//赞同挚友增加 functionagreeAddFriend(id){
let nowTime
=commonUtil.getNowTime();
$.post(ctx
+ "/imsFriend/save", {
id:id,
isAgree:
1,
updataTime: nowTime,
},
function(data) {if(data.flag) {
$.post(ctx
+ "/imsFriend/save", {
userId: data.data.friendId,
friendId: data.data.userId,
friendType:
1,
friendRemark:
"",
isAgree:
1,
createdTime: nowTime,
updataTime: nowTime,
},
function(data) {if(data.flag) {
tip.msg({text:
"你们已是挚友了,能够最先谈天!",time:2000});
}
});
}
});
}
//猎取我的请求挚友,并做小圆点提醒 functiongetApplyFriend(userId){
$.post(ctx
+ "/imsFriend/list", {
friendId: userId,
isAgree:
0,
},
function(data) {if (data.flag && data.data.length > 0) {
$(
"#sysNotification").find(".hz-badge").css("opacity",1);
$(
"#sysNotification").find(".hz-badge").text(data.data.length);
}
});
}

socketChart.js

  在线、离线提醒出来小bug...

  

  2019-05-17更新

  题目找到了,是因为我们将联系关系的挚友对象属性名改成了

@OneToOne
@JoinColumn(name
= "friendId",referencedColumnName = "id", insertable = false, updatable = false)
@NotFound(action
=NotFoundAction.IGNORE)private ImsUser friendUser;//挚友

  但在猎取在线挚友那边照样,getUser();,致使数据紊乱,bug修正:改成getFriendUser();便可

/*** 猎取在线挚友*/@Overridepublic Result<List<ImsUserVo>>getOnlineList(ImsFriendVo imsFriendVo) {
imsFriendVo.setIsAgree(
1);//挚友列表 List<ImsFriendVo> friendList =list(imsFriendVo).getData();//在线挚友列表 ArrayList<ImsUserVo> onlineFriendList = new ArrayList<>();//遍历friendList for(ImsFriendVo imsFriendVo1 : friendList){
ImsUserVo imsUserVo
=imsFriendVo1.getUser();if (!StringUtils.isEmpty(WebSocketServer.getSessionMap().get(imsUserVo.getId().toString()))) {
onlineFriendList.add(imsUserVo);
}
}
returnResult.of(onlineFriendList);
}

 

 

  跋文

  第二版临时记录到这,第三版延续更新中...

Last modification:March 25, 2020
如果觉得我的文章对你有用,请随意赞赏