Browse Source

Merge remote-tracking branch 'origin/v_2.0.0' into v_2.0.0

master
blue 2 years ago
parent
commit
5a1b94701e
  1. 2
      im-server/src/main/java/com/bx/imserver/netty/IMChannelHandler.java
  2. 5
      im-server/src/main/java/com/bx/imserver/netty/processor/HeartbeatProcessor.java
  3. 2
      im-ui/package.json
  4. 116
      im-uniapp/App.vue
  5. 3
      im-uniapp/common/request.js
  6. 9
      im-uniapp/common/wssocket.js
  7. 6
      im-uniapp/components/group-member-selector/group-member-selector.vue
  8. 2
      im-uniapp/pages/group/group-info.vue
  9. 10
      im-uniapp/static/icon/iconfont.css
  10. BIN
      im-uniapp/static/icon/iconfont.ttf
  11. 11
      im-uniapp/store/chatStore.js

2
im-server/src/main/java/com/bx/imserver/netty/IMChannelHandler.java

@ -74,7 +74,7 @@ public class IMChannelHandler extends SimpleChannelInboundHandler<IMSendInfo> {
RedisTemplate<String, Object> redisTemplate = SpringContextHolder.getBean("redisTemplate");
String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, userId.toString(), terminal.toString());
redisTemplate.delete(key);
log.info("断开连接,userId:{},终端类型:{}", userId, terminal);
log.info("断开连接,userId:{},终端类型:{},{}", userId, terminal, ctx.channel().id().asLongText());
}
}

5
im-server/src/main/java/com/bx/imserver/netty/processor/HeartbeatProcessor.java

@ -30,7 +30,7 @@ public class HeartbeatProcessor extends AbstractMessageProcessor<IMHeartbeatInfo
IMSendInfo sendInfo = new IMSendInfo();
sendInfo.setCmd(IMCmdType.HEART_BEAT.code());
ctx.channel().writeAndFlush(sendInfo);
;
// 设置属性
AttributeKey<Long> heartBeatAttr = AttributeKey.valueOf(ChannelAttrKey.HEARTBEAT_TIMES);
Long heartbeatTimes = ctx.channel().attr(heartBeatAttr).get();
@ -44,6 +44,9 @@ public class HeartbeatProcessor extends AbstractMessageProcessor<IMHeartbeatInfo
String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, userId.toString(), terminal.toString());
redisTemplate.expire(key, IMConstant.ONLINE_TIMEOUT_SECOND, TimeUnit.SECONDS);
}
AttributeKey<Long> userIdAttr = AttributeKey.valueOf(ChannelAttrKey.USER_ID);
Long userId = ctx.channel().attr(userIdAttr).get();
log.info("心跳,userId:{},{}",userId,ctx.channel().id().asLongText());
}
@Override

2
im-ui/package.json

@ -13,7 +13,7 @@
"element-ui": "^2.15.10",
"js-audio-recorder": "^1.0.7",
"sass": "^1.47.0",
"sass-loader": "^7.3.1",
"sass-loader": "^10.1.1",
"vue": "^2.6.11",
"vue-axios": "^3.5.0",
"vue-router": "^3.3.3",

116
im-uniapp/App.vue

@ -5,11 +5,12 @@
import * as enums from './common/enums';
import * as wsApi from './common/wssocket';
import UNI_APP from '@/.env.js'
export default {
data() {
return {
audioTip: null
audioTip: null,
reconnecting: false //
}
},
methods: {
@ -28,6 +29,14 @@
wsApi.init();
wsApi.connect(UNI_APP.WS_URL, loginInfo.accessToken);
wsApi.onConnect(() => {
//
if(this.reconnecting){
this.reconnecting = false;
uni.showToast({
title: "已重新连接",
icon: 'none'
})
}
// 线
this.pullPrivateOfflineMessage(store.state.chatStore.privateMsgMaxId);
this.pullGroupOfflineMessage(store.state.chatStore.groupMsgMaxId);
@ -49,35 +58,30 @@
}
});
wsApi.onClose((res) => {
console.log("ws断开",res);
// 1000
if (res.code != 1000) {
console.log("ws断开", res);
// 3099
if (res.code != 3099) {
//
uni.showToast({
title: '连接已断开,尝试重新连接...',
icon: 'none',
})
let loginInfo = uni.getStorageSync("loginInfo")
wsApi.reconnect(UNI_APP.WS_URL, loginInfo.accessToken);
this.reconnectWs();
}
})
},
pullPrivateOfflineMessage(minId) {
store.commit("loadingPrivateMsg",true)
store.commit("loadingPrivateMsg", true)
http({
url: "/message/private/pullOfflineMessage?minId=" + minId,
method: 'GET'
}).catch(()=>{
store.commit("loadingPrivateMsg",false)
}).catch(() => {
store.commit("loadingPrivateMsg", false)
})
},
pullGroupOfflineMessage(minId) {
store.commit("loadingGroupMsg",true)
store.commit("loadingGroupMsg", true)
http({
url: "/message/group/pullOfflineMessage?minId=" + minId,
method: 'GET'
}).catch(()=>{
store.commit("loadingGroupMsg",false)
}).catch(() => {
store.commit("loadingGroupMsg", false)
})
},
handlePrivateMessage(msg) {
@ -96,7 +100,9 @@
}
// ,
if (msg.type == enums.MESSAGE_TYPE.RECEIPT) {
store.commit("readedMessage", { friendId: msg.sendId })
store.commit("readedMessage", {
friendId: msg.sendId
})
return;
}
//
@ -112,17 +118,17 @@
//
if (msgType.isRtcPrivate(msg.type)) {
// #ifdef MP-WEIXIN
//
return;
//
return;
// #endif
//
let delayTime = 100;
if(msg.type == enums.MESSAGE_TYPE.RTC_CALL_VOICE
|| msg.type == enums.MESSAGE_TYPE.RTC_CALL_VIDEO){
let mode = msg.type == enums.MESSAGE_TYPE.RTC_CALL_VIDEO? "video":"voice";
if (msg.type == enums.MESSAGE_TYPE.RTC_CALL_VOICE ||
msg.type == enums.MESSAGE_TYPE.RTC_CALL_VIDEO) {
let mode = msg.type == enums.MESSAGE_TYPE.RTC_CALL_VIDEO ? "video" : "voice";
let pages = getCurrentPages();
let curPage = pages[pages.length-1].route;
if(curPage != "pages/chat/chat-private-video"){
let curPage = pages[pages.length - 1].route;
if (curPage != "pages/chat/chat-private-video") {
const friendInfo = encodeURIComponent(JSON.stringify(friend));
uni.navigateTo({
url: `/pages/chat/chat-private-video?mode=${mode}&friend=${friendInfo}&isHost=false`
@ -131,8 +137,8 @@
}
}
setTimeout(() => {
uni.$emit('WS_RTC_PRIVATE',msg);
},delayTime)
uni.$emit('WS_RTC_PRIVATE', msg);
}, delayTime)
return;
}
let chatInfo = {
@ -152,7 +158,7 @@
handleGroupMessage(msg) {
//
if (msg.type == enums.MESSAGE_TYPE.LOADING) {
store.commit("loadingGroupMsg",JSON.parse(msg.content))
store.commit("loadingGroupMsg", JSON.parse(msg.content))
return;
}
//
@ -189,15 +195,15 @@
//
if (msgType.isRtcGroup(msg.type)) {
// #ifdef MP-WEIXIN
//
return;
//
return;
// #endif
//
let delayTime = 100;
if(msg.type == enums.MESSAGE_TYPE.RTC_GROUP_SETUP){
if (msg.type == enums.MESSAGE_TYPE.RTC_GROUP_SETUP) {
let pages = getCurrentPages();
let curPage = pages[pages.length-1].route;
if(curPage != "pages/chat/chat-group-video"){
let curPage = pages[pages.length - 1].route;
if (curPage != "pages/chat/chat-group-video") {
const userInfos = encodeURIComponent(msg.content);
const inviterId = msg.sendId;
const groupId = msg.groupId
@ -210,11 +216,11 @@
}
// chat-group-video
setTimeout(() => {
uni.$emit('WS_RTC_GROUP',msg);
},delayTime)
uni.$emit('WS_RTC_GROUP', msg);
}, delayTime)
return;
}
let chatInfo = {
type: 'GROUP',
targetId: group.id,
@ -275,11 +281,37 @@
// this.audioTip.src = "/static/audio/tip.wav";
// this.audioTip.play();
},
isExpired(loginInfo){
if(!loginInfo || !loginInfo.expireTime){
isExpired(loginInfo) {
if (!loginInfo || !loginInfo.expireTime) {
return true;
}
return loginInfo.expireTime < new Date().getTime();
},
reconnectWs() {
//
this.reconnecting = true;
// token
this.reloadUserInfo().then((userInfo) => {
uni.showToast({
title: '连接已断开,尝试重新连接...',
icon: 'none',
})
store.commit("setUserInfo", userInfo);
//
let loginInfo = uni.getStorageSync("loginInfo")
wsApi.reconnect(UNI_APP.WS_URL, loginInfo.accessToken);
}).catch(() => {
// 5s
setTimeout(()=>{
this.reconnectWs();
},5000)
})
},
reloadUserInfo() {
return http({
url: '/user/self',
method: 'GET'
})
}
},
onLaunch() {
@ -293,12 +325,12 @@
uni.switchTab({
url: "/pages/chat/chat"
})
} else{
} else {
//
// #ifdef H5
uni.navigateTo({
url: "/pages/login/login"
})
uni.navigateTo({
url: "/pages/login/login"
})
// #endif
}
}

3
im-uniapp/common/request.js

@ -61,7 +61,8 @@ const request = (options) => {
},
fail(error) {
uni.showToast({
title: "网络似乎有点不给力,请稍后重试",
title: "网络似乎有点不给力哟",
icon: "none",
duration: 1500
})
return reject(error)

9
im-uniapp/common/wssocket.js

@ -6,6 +6,7 @@ let connectCallBack = null;
let isConnect = false; //连接标识 避免重复连接
let rec = null;
let isInit = false;
let lastConnectTime = new Date(); // 最后一次连接时间
let init = () => {
// 防止重复初始化
@ -64,6 +65,7 @@ let connect = (url, token) => {
if (isConnect) {
return;
}
lastConnectTime = new Date();
uni.connectSocket({
url: wsurl,
success: (res) => {
@ -86,10 +88,13 @@ let reconnect = (wsurl, accessToken) => {
//如果已经连上就不在重连了
return;
}
// 延迟10秒重连 避免过多次过频繁请求重连
let timeDiff = new Date().getTime() - lastConnectTime.getTime()
let delay = timeDiff < 10000 ? 10000 - timeDiff : 0;
rec && clearTimeout(rec);
rec = setTimeout(function() { // 延迟15秒重连 避免过多次过频繁请求重连
rec = setTimeout(function() {
connect(wsurl, accessToken);
}, 15000);
}, delay);
};
//设置关闭连接

6
im-uniapp/components/group-member-selector/group-member-selector.vue

@ -4,7 +4,7 @@
<view class="top-bar">
<view class="top-tip">选择成员</view>
<button class="top-btn" type="warn" size="mini" @click="onClean()">清空 </button>
<button class="top--btn" type="primary" size="mini" @click="onOk()">确定({{checkedIds.length}})
<button class="top-btn" type="primary" size="mini" @click="onOk()">确定({{checkedIds.length}})
</button>
</view>
<scroll-view v-show="checkedIds.length>0" scroll-x="true" scroll-left="120">
@ -120,7 +120,7 @@
display: flex;
align-items: center;
height: 70rpx;
padding: 10rpx;
padding: 10rpx 30rpx;
.top-tip {
flex: 1;
@ -135,7 +135,7 @@
display: flex;
align-items: center;
height: 90rpx;
padding: 0 30rpx;
.user-item {
padding: 3rpx;
}

2
im-uniapp/pages/group/group-info.vue

@ -112,6 +112,7 @@
url:"/pages/group/group"
});
this.$store.commit("removeGroup", this.groupId);
this.$store.commit("removeGroupChat",this.groupId);
},100)
}
})
@ -141,6 +142,7 @@
url:"/pages/group/group"
});
this.$store.commit("removeGroup", this.groupId);
this.$store.commit("removeGroupChat",this.groupId);
},100)
}
})

10
im-uniapp/static/icon/iconfont.css

@ -1,6 +1,6 @@
@font-face {
font-family: "iconfont"; /* Project id 4272106 */
src: url('iconfont.ttf?t=1711870080646') format('truetype');
src: url('iconfont.ttf?t=1719727774055') format('truetype');
}
.iconfont {
@ -11,6 +11,10 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-receipt:before {
content: "\e601";
}
.icon-pause:before {
content: "\e669";
}
@ -35,10 +39,6 @@
content: "\e685";
}
.icon-receipt:before {
content: "\e61a";
}
.icon-ok:before {
content: "\e65a";
}

BIN
im-uniapp/static/icon/iconfont.ttf

Binary file not shown.

11
im-uniapp/store/chatStore.js

@ -133,6 +133,15 @@ export default {
}
}
},
removeGroupChat(state, groupId) {
let chats = this.getters.findChats();
for (let idx in chats) {
if (chats[idx].type == 'GROUP' &&
chats[idx].targetId == groupId) {
this.commit("removeChat", idx);
}
}
},
moveTop(state, idx) {
let chats = this.getters.findChats();
let chat = chats[idx];
@ -294,6 +303,8 @@ export default {
});
// 将消息一次性装载回来
state.chats = cacheChats;
// 断线重连后不能使用缓存模式,否则会导致聊天窗口的消息不刷新
cacheChats = state.chats;
this.commit("saveToStorage");
},
saveToStorage(state) {

Loading…
Cancel
Save