媒介
接上一版,这一版的页面与功用都有所优化,详细以下:
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);
}
@Overridepublic 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);
}
@Overridepublic 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);
}
跋文
第二版临时记录到这,第三版延续更新中...
Comment here is closed