{{tip}}
@@ -191,7 +191,7 @@
\ No newline at end of file
diff --git a/im-ui/src/api/enums.js b/im-ui/src/api/enums.js
index 0e6a1b1..0157962 100644
--- a/im-ui/src/api/enums.js
+++ b/im-ui/src/api/enums.js
@@ -1,18 +1,17 @@
-
const MESSAGE_TYPE = {
TEXT: 0,
- IMAGE:1,
- FILE:2,
- AUDIO:3,
- VIDEO:4,
- RT_VOICE:5,
- RT_VIDEO:6,
- RECALL:10,
- READED:11,
- RECEIPT:12,
- TIP_TIME:20,
- TIP_TEXT:21,
- LOADDING:30,
+ IMAGE: 1,
+ FILE: 2,
+ AUDIO: 3,
+ VIDEO: 4,
+ RT_VOICE: 5,
+ RT_VIDEO: 6,
+ RECALL: 10,
+ READED: 11,
+ RECEIPT: 12,
+ TIP_TIME: 20,
+ TIP_TEXT: 21,
+ LOADDING: 30,
RTC_CALL_VOICE: 100,
RTC_CALL_VIDEO: 101,
RTC_ACCEPT: 102,
@@ -20,7 +19,19 @@ const MESSAGE_TYPE = {
RTC_CANCEL: 104,
RTC_FAILED: 105,
RTC_HANDUP: 106,
- RTC_CANDIDATE: 107
+ RTC_CANDIDATE: 107,
+ RTC_GROUP_SETUP: 200,
+ RTC_GROUP_ACCEPT: 201,
+ RTC_GROUP_REJECT: 202,
+ RTC_GROUP_FAILED: 203,
+ RTC_GROUP_CANCEL: 204,
+ RTC_GROUP_QUIT: 205,
+ RTC_GROUP_INVITE: 206,
+ RTC_GROUP_JOIN: 207,
+ RTC_GROUP_OFFER: 208,
+ RTC_GROUP_ANSWER: 209,
+ RTC_GROUP_CANDIDATE: 210,
+ RTC_GROUP_DEVICE: 211
}
const RTC_STATE = {
@@ -28,7 +39,7 @@ const RTC_STATE = {
WAIT_CALL: 1, // 呼叫后等待
WAIT_ACCEPT: 2, // 被呼叫后等待
ACCEPTED: 3, // 已接受聊天,等待建立连接
- CHATING:4 // 聊天中
+ CHATING: 4 // 聊天中
}
const TERMINAL_TYPE = {
@@ -39,8 +50,8 @@ const TERMINAL_TYPE = {
const MESSAGE_STATUS = {
UNSEND: 0,
SENDED: 1,
- RECALL:2,
- READED:3
+ RECALL: 2,
+ READED: 3
}
@@ -49,4 +60,4 @@ export {
RTC_STATE,
TERMINAL_TYPE,
MESSAGE_STATUS
-}
+}
\ No newline at end of file
diff --git a/im-ui/src/assets/iconfont/iconfont.css b/im-ui/src/assets/iconfont/iconfont.css
index ff4113e..8c5b819 100644
--- a/im-ui/src/assets/iconfont/iconfont.css
+++ b/im-ui/src/assets/iconfont/iconfont.css
@@ -1,6 +1,6 @@
@font-face {
font-family: "iconfont"; /* Project id 3791506 */
- src: url('iconfont.ttf?t=1714220334746') format('truetype');
+ src: url('iconfont.ttf?t=1718373714629') format('truetype');
}
.iconfont {
@@ -11,6 +11,38 @@
-moz-osx-font-smoothing: grayscale;
}
+.icon-invite-rtc:before {
+ content: "\e65f";
+}
+
+.icon-quit:before {
+ content: "\e606";
+}
+
+.icon-camera-off:before {
+ content: "\e6b5";
+}
+
+.icon-speaker-off:before {
+ content: "\ea3c";
+}
+
+.icon-microphone-on:before {
+ content: "\e63b";
+}
+
+.icon-speaker-on:before {
+ content: "\e6a4";
+}
+
+.icon-camera-on:before {
+ content: "\e627";
+}
+
+.icon-microphone-off:before {
+ content: "\efe5";
+}
+
.icon-chat:before {
content: "\e600";
}
diff --git a/im-ui/src/assets/iconfont/iconfont.ttf b/im-ui/src/assets/iconfont/iconfont.ttf
index 63ec967c2b7a9bbfc8dc6b19d650bedd6824092b..1697727cd9bc8b7cd880261c65193ec0389fb641 100644
GIT binary patch
delta 3009
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
KJKN|<9Qij=93Ghf
delta 643
zcmZvYJ!lj`7>3_(X7~QroPv6sTdWunAzh*tIgoTItgIvox+XD)pQzx=`7ED|1As6^tZ`qv$for&`HAc
zelVU`T$&B5V@E!7{t;up6?WP(idU@H7zcO4*1TVR*LV+%ut6=fm+mc3M^|=%!!aA)
zJlj4seK0vV*xwn(_CHy1
z{#S{
@@ -36,8 +36,8 @@
x
+ @compositionstart="onEditorCompositionStart"
+ @compositionend="onEditorCompositionEnd" @input="onEditorInput"
+ :placeholder="placeholder" @blur="onEditBoxBlur()" @keydown.down="onKeyDown"
+ @keydown.up="onKeyUp" @keydown.enter.prevent="onKeyEnter">x
@@ -85,853 +89,905 @@
-
+
+
+
\ No newline at end of file
+
\ No newline at end of file
diff --git a/im-ui/src/components/common/HeadImage.vue b/im-ui/src/components/common/HeadImage.vue
index eccba60..91eec68 100644
--- a/im-ui/src/components/common/HeadImage.vue
+++ b/im-ui/src/components/common/HeadImage.vue
@@ -28,6 +28,16 @@
type: Number,
default: 50
},
+ width: {
+ type: Number
+ },
+ height: {
+ type: Number
+ },
+ radius:{
+ type: String,
+ default: "10%"
+ },
url: {
type: String
},
@@ -54,12 +64,18 @@
}
},
computed:{
- avatarImageStyle(){
- return `width:${this.size}px; height:${this.size}px;`
+ avatarImageStyle() {
+ let w = this.width ? this.width : this.size;
+ let h = this.height ? this.height : this.size;
+ return `width:${w}px; height:${h}px;
+ border-radius: ${this.radius};`
},
- avatarTextStyle(){
- return `width: ${this.size}px;height:${this.size}px;
- color:${this.textColor};font-size:${this.size*0.6}px;`
+ avatarTextStyle() {
+ let w = this.width ? this.width : this.size;
+ let h = this.height ? this.height : this.size;
+ return `width: ${w}px;height:${h}px;
+ color:${this.textColor};font-size:${w*0.6}px;
+ border-radius: ${this.radius};`
},
textColor(){
let hash = 0;
@@ -79,7 +95,7 @@
.avatar-image {
position: relative;
overflow: hidden;
- border-radius: 10%;
+ display: block;
}
.avatar-text{
diff --git a/im-ui/src/components/group/AddGroupMember.vue b/im-ui/src/components/group/AddGroupMember.vue
index d60be28..d41f815 100644
--- a/im-ui/src/components/group/AddGroupMember.vue
+++ b/im-ui/src/components/group/AddGroupMember.vue
@@ -136,33 +136,7 @@
border-radius: 5px;
overflow: hidden;
- .el-checkbox {
- display: flex;
- align-items: center;
-
- //修改选中框的大小
- .el-checkbox__inner {
- width: 20px;
- height: 20px;
-
- //修改选中框中的对勾的大小和位置
- &::after {
- height: 12px;
- left: 7px;
- }
- }
-
- //修改点击文字颜色不变
- .el-checkbox__input.is-checked+.el-checkbox__label {
- color: #333333;
- }
-
- .el-checkbox__label {
- line-height: 20px;
- padding-left: 8px;
- }
- }
-
+
.agm-friend-checkbox {
margin-right: 20px;
}
diff --git a/im-ui/src/components/rtc/RtcPrivateAcceptor.vue b/im-ui/src/components/rtc/RtcPrivateAcceptor.vue
index 193bc2f..95d5d52 100644
--- a/im-ui/src/components/rtc/RtcPrivateAcceptor.vue
+++ b/im-ui/src/components/rtc/RtcPrivateAcceptor.vue
@@ -15,7 +15,7 @@
import HeadImage from '../common/HeadImage.vue';
export default {
- name: "videoAcceptor",
+ name: "rtcPrivateAcceptor",
components: {
HeadImage
},
diff --git a/im-ui/src/main.js b/im-ui/src/main.js
index 9ced174..25dfd46 100644
--- a/im-ui/src/main.js
+++ b/im-ui/src/main.js
@@ -21,6 +21,7 @@ Vue.prototype.$http = httpRequest // http请求方法
Vue.prototype.$emo = emotion; // emo表情
Vue.prototype.$elm = element; // 元素操作
Vue.prototype.$enums = enums; // 枚举
+Vue.prototype.$eventBus = new Vue(); // 全局事件
Vue.config.productionTip = false;
new Vue({
diff --git a/im-ui/src/view/Home.vue b/im-ui/src/view/Home.vue
index 0ac36cb..1bb97a4 100644
--- a/im-ui/src/view/Home.vue
+++ b/im-ui/src/view/Home.vue
@@ -42,6 +42,7 @@
@close="$store.commit('closeFullImageBox')">
+
@@ -52,6 +53,7 @@
import FullImage from '../components/common/FullImage.vue';
import RtcPrivateVideo from '../components/rtc/RtcPrivateVideo.vue';
import RtcPrivateAcceptor from '../components/rtc/RtcPrivateAcceptor.vue';
+ import RtcGroupVideo from '../components/rtc/RtcGroupVideo.vue';
export default {
components: {
@@ -60,7 +62,8 @@
UserInfo,
FullImage,
RtcPrivateVideo,
- RtcPrivateAcceptor
+ RtcPrivateAcceptor,
+ RtcGroupVideo
},
data() {
return {
@@ -70,6 +73,12 @@
},
methods: {
init() {
+ this.$eventBus.$on('openGroupVideo', (rctInfo)=>{
+ // 进入多人视频通话
+ console.log(this.$refs.rtcGroupVideo)
+ this.$refs.rtcGroupVideo.open(rctInfo);
+ });
+
this.$store.dispatch("load").then(() => {
// ws初始化
this.$wsApi.connect(process.env.VUE_APP_WS_URL, sessionStorage.getItem("accessToken"));
@@ -153,9 +162,8 @@
})
},
insertPrivateMessage(friend, msg) {
- // webrtc 信令
- if (msg.type >= this.$enums.MESSAGE_TYPE.RTC_CALL_VOICE &&
- msg.type <= this.$enums.MESSAGE_TYPE.RTC_CANDIDATE) {
+ // 单人webrtc 信令
+ if (msg.type >= 100 && msg.type <= 199) {
let rtcInfo = this.$store.state.userStore.rtcInfo;
// 呼叫
if (msg.type == this.$enums.MESSAGE_TYPE.RTC_CALL_VOICE ||
@@ -180,7 +188,8 @@
// 插入消息
this.$store.commit("insertMessage", msg);
// 播放提示音
- if (!msg.selfSend && msg.status != this.$enums.MESSAGE_STATUS.READED) {
+ if (!msg.selfSend && msg.type < 10
+ && msg.status != this.$enums.MESSAGE_STATUS.READED) {
this.playAudioTip();
}
},
@@ -214,12 +223,20 @@
}
// 标记这条消息是不是自己发的
msg.selfSend = msg.sendId == this.$store.state.userStore.userInfo.id;
+ // 群视频信令
+ if (msg.type >= 200 && msg.type <= 299) {
+ this.$nextTick(()=>{
+ this.$refs.rtcGroupVideo.onRTCMessage(msg);
+ })
+ return;
+ }
this.loadGroupInfo(msg.groupId).then((group) => {
// 插入群聊消息
this.insertGroupMessage(group, msg);
})
},
insertGroupMessage(group, msg) {
+
let chatInfo = {
type: 'GROUP',
targetId: group.id,
@@ -231,7 +248,8 @@
// 插入消息
this.$store.commit("insertMessage", msg);
// 播放提示音
- if (!msg.selfSend && msg.status != this.$enums.MESSAGE_STATUS.READED) {
+ if (!msg.selfSend && msg.type < 10
+ && msg.status != this.$enums.MESSAGE_STATUS.READED) {
this.playAudioTip();
}
},
diff --git a/im-uniapp/pages/chat/chat-box.vue b/im-uniapp/pages/chat/chat-box.vue
index 146fafc..765b9b2 100644
--- a/im-uniapp/pages/chat/chat-box.vue
+++ b/im-uniapp/pages/chat/chat-box.vue
@@ -81,11 +81,11 @@
-
+
视频通话
-
+
语音通话
@@ -110,7 +110,7 @@
+ @complete="onInviteOk">
@@ -175,18 +175,18 @@
},
onRtCall(msgInfo) {
if (msgInfo.type == this.$enums.MESSAGE_TYPE.RT_VOICE) {
- this.onVoiceCall();
+ this.onPriviteVoice();
} else if (msgInfo.type == this.$enums.MESSAGE_TYPE.RT_VIDEO) {
- this.onVideoCall();
+ this.onPriviteVideo();
}
},
- onVideoCall() {
+ onPriviteVideo() {
const friendInfo = encodeURIComponent(JSON.stringify(this.friend));
uni.navigateTo({
url: `/pages/chat/chat-private-video?mode=video&friend=${friendInfo}&isHost=true`
})
},
- onVoiceCall() {
+ onPriviteVoice() {
const friendInfo = encodeURIComponent(JSON.stringify(this.friend));
uni.navigateTo({
url: `/pages/chat/chat-private-video?mode=voice&friend=${friendInfo}&isHost=true`
@@ -208,7 +208,10 @@
}
})
},
- onSelectMember(ids) {
+ onInviteOk(ids) {
+ if(ids.length < 2){
+ return;
+ }
let users = [];
ids.forEach(id => {
let m = this.groupMembers.find(m => m.userId == id);
@@ -217,7 +220,8 @@
id: m.userId,
nickName: m.aliasName,
headImage: m.headImage,
- isCamera: false
+ isCamera: false,
+ isMicroPhone: true
})
})
const groupId = this.group.id;
From 9ac5c36796054a456d5ef10061dc98bd4caa423e Mon Sep 17 00:00:00 2001
From: xsx <825657193@qq.com>
Date: Sun, 16 Jun 2024 14:35:29 +0800
Subject: [PATCH 08/18] =?UTF-8?q?feat:=20=E5=A4=9A=E4=BA=BA=E9=9F=B3?=
=?UTF-8?q?=E8=A7=86=E9=A2=91=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
im-ui/src/api/camera.js | 76 +++++++++
im-ui/src/api/eventBus.js | 3 +
im-ui/src/api/rtcGroupApi.js | 156 +++++++++++++++++++
im-ui/src/api/webrtc.js | 117 ++++++++++++++
im-ui/src/components/rtc/RtcGroupJoin.vue | 116 ++++++++++++++
im-ui/src/store/configStore.js | 32 ++++
im-uniapp/hybrid/html/index.html | 1 -
im-uniapp/hybrid/html/rtc-group/index.html | 13 ++
im-uniapp/hybrid/html/rtc-private/index.html | 13 ++
9 files changed, 526 insertions(+), 1 deletion(-)
create mode 100644 im-ui/src/api/camera.js
create mode 100644 im-ui/src/api/eventBus.js
create mode 100644 im-ui/src/api/rtcGroupApi.js
create mode 100644 im-ui/src/api/webrtc.js
create mode 100644 im-ui/src/components/rtc/RtcGroupJoin.vue
create mode 100644 im-ui/src/store/configStore.js
delete mode 100644 im-uniapp/hybrid/html/index.html
create mode 100644 im-uniapp/hybrid/html/rtc-group/index.html
create mode 100644 im-uniapp/hybrid/html/rtc-private/index.html
diff --git a/im-ui/src/api/camera.js b/im-ui/src/api/camera.js
new file mode 100644
index 0000000..be3a1ae
--- /dev/null
+++ b/im-ui/src/api/camera.js
@@ -0,0 +1,76 @@
+
+class ImCamera {
+ constructor() {
+ this.stream = null;
+ }
+}
+
+ImCamera.prototype.isEnable = function() {
+ return !!navigator && !!navigator.mediaDevices && !!navigator.mediaDevices.getUserMedia;
+}
+
+ImCamera.prototype.openVideo = function(isFacing) {
+ return new Promise((resolve, reject) => {
+ if(this.stream){
+ this.close()
+ }
+ let facingMode = isFacing ? "user" : "environment";
+ let constraints = {
+ video: {
+ facingMode: facingMode
+ },
+ audio: {
+ echoCancellation: true, //音频开启回音消除
+ noiseSuppression: true // 开启降噪
+ }
+ }
+ console.log("getUserMedia")
+ navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
+ console.log("摄像头打开")
+ this.stream = stream;
+ resolve(stream);
+ }).catch((e) => {
+ console.log(e)
+ console.log("摄像头未能正常打开")
+ reject({
+ code: 0,
+ message: "摄像头未能正常打开"
+ })
+ })
+ })
+}
+
+
+ImCamera.prototype.openAudio = function() {
+ return new Promise((resolve, reject) => {
+ let constraints = {
+ video: false,
+ audio: {
+ echoCancellation: true, //音频开启回音消除
+ noiseSuppression: true // 开启降噪
+ }
+ }
+ navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
+ this.stream = stream;
+ resolve(stream);
+ }).catch(() => {
+ console.log("麦克风未能正常打开")
+ reject({
+ code: 0,
+ message: "麦克风未能正常打开"
+ })
+ })
+
+ })
+}
+
+ImCamera.prototype.close = function() {
+ // 停止流
+ if (this.stream) {
+ this.stream.getTracks().forEach((track) => {
+ track.stop();
+ });
+ }
+}
+
+export default ImCamera;
\ No newline at end of file
diff --git a/im-ui/src/api/eventBus.js b/im-ui/src/api/eventBus.js
new file mode 100644
index 0000000..a72b416
--- /dev/null
+++ b/im-ui/src/api/eventBus.js
@@ -0,0 +1,3 @@
+import Vue from 'vue';
+
+export default new Vue();
\ No newline at end of file
diff --git a/im-ui/src/api/rtcGroupApi.js b/im-ui/src/api/rtcGroupApi.js
new file mode 100644
index 0000000..58e8409
--- /dev/null
+++ b/im-ui/src/api/rtcGroupApi.js
@@ -0,0 +1,156 @@
+import http from './httpRequest.js'
+
+class RtcGroupApi {
+ constructor() {
+ this.http = http;
+ }
+}
+
+
+RtcGroupApi.prototype.setup = function(groupId, userInfos) {
+ let formData = {
+ groupId,
+ userInfos
+ }
+ return this.http({
+ url: '/webrtc/group/setup',
+ method: 'post',
+ data: formData
+ })
+}
+
+RtcGroupApi.prototype.accept = function(groupId) {
+ return this.http({
+ url: '/webrtc/group/accept?groupId='+groupId,
+ method: 'post'
+ })
+}
+
+RtcGroupApi.prototype.reject = function(groupId) {
+ return this.http({
+ url: '/webrtc/group/reject?groupId='+groupId,
+ method: 'post'
+ })
+}
+
+RtcGroupApi.prototype.failed = function(groupId,reason) {
+ let formData = {
+ groupId,
+ reason
+ }
+ return this.http({
+ url: '/webrtc/group/failed',
+ method: 'post',
+ data: formData
+ })
+}
+
+
+RtcGroupApi.prototype.join = function(groupId) {
+ return this.http({
+ url: '/webrtc/group/join?groupId='+groupId,
+ method: 'post'
+ })
+}
+
+RtcGroupApi.prototype.invite = function(groupId, userInfos) {
+ let formData = {
+ groupId,
+ userInfos
+ }
+ return this.http({
+ url: '/webrtc/group/invite',
+ method: 'post',
+ data: formData
+ })
+}
+
+
+RtcGroupApi.prototype.offer = function(groupId, userId, offer) {
+ let formData = {
+ groupId,
+ userId,
+ offer
+ }
+ return this.http({
+ url: '/webrtc/group/offer',
+ method: 'post',
+ data: formData
+ })
+}
+
+RtcGroupApi.prototype.answer = function(groupId, userId, answer) {
+ let formData = {
+ groupId,
+ userId,
+ answer
+ }
+ return this.http({
+ url: '/webrtc/group/answer',
+ method: 'post',
+ data: formData
+ })
+}
+
+RtcGroupApi.prototype.quit = function(groupId) {
+ return this.http({
+ url: '/webrtc/group/quit?groupId=' + groupId,
+ method: 'post'
+ })
+}
+
+RtcGroupApi.prototype.cancel = function(groupId) {
+ return this.http({
+ url: '/webrtc/group/cancel?groupId=' + groupId,
+ method: 'post'
+ })
+}
+
+RtcGroupApi.prototype.candidate = function(groupId, userId, candidate) {
+ let formData = {
+ groupId,
+ userId,
+ candidate
+ }
+ return this.http({
+ url: '/webrtc/group/candidate',
+ method: 'post',
+ data: formData
+ })
+}
+
+RtcGroupApi.prototype.device = function(groupId, isCamera, isMicroPhone) {
+ let formData = {
+ groupId,
+ isCamera,
+ isMicroPhone
+ }
+ return this.http({
+ url: '/webrtc/group/device',
+ method: 'post',
+ data: formData
+ })
+}
+
+
+RtcGroupApi.prototype.candidate = function(groupId, userId, candidate) {
+ let formData = {
+ groupId,
+ userId,
+ candidate
+ }
+ return this.http({
+ url: '/webrtc/group/candidate',
+ method: 'post',
+ data: formData
+ })
+}
+
+RtcGroupApi.prototype.heartbeat = function(groupId) {
+ return this.http({
+ url: '/webrtc/group/heartbeat?groupId=' + groupId,
+ method: 'post'
+ })
+}
+
+export default RtcGroupApi;
\ No newline at end of file
diff --git a/im-ui/src/api/webrtc.js b/im-ui/src/api/webrtc.js
new file mode 100644
index 0000000..359118b
--- /dev/null
+++ b/im-ui/src/api/webrtc.js
@@ -0,0 +1,117 @@
+
+class ImWebRtc {
+ constructor() {
+ this.configuration = {}
+ this.stream = null;
+ }
+}
+
+ImWebRtc.prototype.isEnable = function() {
+ window.RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window
+ .mozRTCPeerConnection;
+ window.RTCSessionDescription = window.RTCSessionDescription || window.webkitRTCSessionDescription || window
+ .mozRTCSessionDescription;
+ window.RTCIceCandidate = window.RTCIceCandidate || window.webkitRTCIceCandidate || window
+ .mozRTCIceCandidate;
+ return !!window.RTCPeerConnection;
+}
+
+ImWebRtc.prototype.init = function(configuration) {
+ this.configuration = configuration;
+}
+
+ImWebRtc.prototype.setupPeerConnection = function(callback) {
+ this.peerConnection = new RTCPeerConnection(this.configuration);
+ this.peerConnection.ontrack = (e) => {
+ // 对方的视频流
+ callback(e.streams[0]);
+ };
+}
+
+
+ImWebRtc.prototype.setStream = function(stream) {
+ if(this.stream){
+ this.peerConnection.removeStream(this.stream)
+ }
+ stream.getTracks().forEach((track) => {
+ this.peerConnection.addTrack(track, stream);
+ });
+ this.stream = stream;
+}
+
+
+ImWebRtc.prototype.onIcecandidate = function(callback) {
+ this.peerConnection.onicecandidate = (event) => {
+ // 追踪到候选信息
+ if (event.candidate) {
+ callback(event.candidate)
+ }
+ }
+}
+
+ImWebRtc.prototype.onStateChange = function(callback) {
+ // 监听连接状态
+ this.peerConnection.oniceconnectionstatechange = (event) => {
+ let state = event.target.iceConnectionState;
+ console.log("ICE连接状态变化: : " + state)
+ callback(state)
+ };
+}
+
+ImWebRtc.prototype.createOffer = function() {
+ return new Promise((resolve, reject) => {
+ const offerParam = {};
+ offerParam.offerToRecieveAudio = 1;
+ offerParam.offerToRecieveVideo = 1;
+ // 创建本地sdp信息
+ this.peerConnection.createOffer(offerParam).then((offer) => {
+ // 设置本地sdp信息
+ this.peerConnection.setLocalDescription(offer);
+ // 发起呼叫请求
+ resolve(offer)
+ }).catch((e) => {
+ reject(e)
+ })
+ });
+}
+
+
+ImWebRtc.prototype.createAnswer = function(offer) {
+ return new Promise((resolve, reject) => {
+ // 设置远端的sdp
+ this.setRemoteDescription(offer);
+ // 创建本地dsp
+ const offerParam = {};
+ offerParam.offerToRecieveAudio = 1;
+ offerParam.offerToRecieveVideo = 1;
+ this.peerConnection.createAnswer(offerParam).then((answer) => {
+ // 设置本地sdp信息
+ this.peerConnection.setLocalDescription(answer);
+ // 接受呼叫请求
+ resolve(answer)
+ }).catch((e) => {
+ reject(e)
+ })
+ });
+}
+
+ImWebRtc.prototype.setRemoteDescription = function(offer) {
+ // 设置对方的sdp信息
+ this.peerConnection.setRemoteDescription(new RTCSessionDescription(offer));
+}
+
+ImWebRtc.prototype.addIceCandidate = function(candidate) {
+ // 添加对方的候选人信息
+ this.peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
+}
+
+ImWebRtc.prototype.close = function(uid) {
+ // 关闭RTC连接
+ if (this.peerConnection) {
+ this.peerConnection.close();
+ this.peerConnection.onicecandidate = null;
+ this.peerConnection.onaddstream = null;
+ }
+}
+
+export default ImWebRtc;
\ No newline at end of file
diff --git a/im-ui/src/components/rtc/RtcGroupJoin.vue b/im-ui/src/components/rtc/RtcGroupJoin.vue
new file mode 100644
index 0000000..7d09b10
--- /dev/null
+++ b/im-ui/src/components/rtc/RtcGroupJoin.vue
@@ -0,0 +1,116 @@
+
+
+
+
+
+
{{'发起人:'+rtcInfo.host.nickName}}
+
+
+
{{rtcInfo.userInfos.length+'人正在通话中'}}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/im-ui/src/store/configStore.js b/im-ui/src/store/configStore.js
new file mode 100644
index 0000000..6debf5a
--- /dev/null
+++ b/im-ui/src/store/configStore.js
@@ -0,0 +1,32 @@
+import http from '../api/httpRequest.js'
+
+export default {
+ state: {
+ webrtc: {}
+ },
+ mutations: {
+ setConfig(state, config) {
+ state.webrtc = config.webrtc;
+ },
+ clear(state){
+ state.webrtc = {};
+ }
+ },
+ actions:{
+ loadConfig(context){
+ return new Promise((resolve, reject) => {
+ http({
+ url: '/system/config',
+ method: 'GET'
+ }).then((config) => {
+ console.log("系统配置",config)
+ context.commit("setConfig",config);
+ resolve();
+ }).catch((res)=>{
+ reject(res);
+ });
+ })
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/im-uniapp/hybrid/html/index.html b/im-uniapp/hybrid/html/index.html
deleted file mode 100644
index 05ff8e2..0000000
--- a/im-uniapp/hybrid/html/index.html
+++ /dev/null
@@ -1 +0,0 @@
-web
\ No newline at end of file
diff --git a/im-uniapp/hybrid/html/rtc-group/index.html b/im-uniapp/hybrid/html/rtc-group/index.html
new file mode 100644
index 0000000..be64c86
--- /dev/null
+++ b/im-uniapp/hybrid/html/rtc-group/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+ 语音通话
+
+
+ 音视频通话为付费功能,有需要请联系作者...
+
+
\ No newline at end of file
diff --git a/im-uniapp/hybrid/html/rtc-private/index.html b/im-uniapp/hybrid/html/rtc-private/index.html
new file mode 100644
index 0000000..6733f82
--- /dev/null
+++ b/im-uniapp/hybrid/html/rtc-private/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+ 视频通话
+
+
+ 音视频通话为付费功能,有需要请联系作者...
+
+
\ No newline at end of file
From 536089f55ef7399af9ce9e77cacd9a1d002a7d36 Mon Sep 17 00:00:00 2001
From: xsx <825657193@qq.com>
Date: Sun, 16 Jun 2024 15:00:53 +0800
Subject: [PATCH 09/18] =?UTF-8?q?feat:=20=E5=A4=9A=E4=BA=BA=E9=9F=B3?=
=?UTF-8?q?=E8=A7=86=E9=A2=91=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/components/group/GroupMemberItem.vue | 70 ++++++++
.../components/group/GroupMemberSelector.vue | 161 ++++++++++++++++++
im-ui/src/components/rtc/RtcGroupVideo.vue | 42 +++++
3 files changed, 273 insertions(+)
create mode 100644 im-ui/src/components/group/GroupMemberItem.vue
create mode 100644 im-ui/src/components/group/GroupMemberSelector.vue
create mode 100644 im-ui/src/components/rtc/RtcGroupVideo.vue
diff --git a/im-ui/src/components/group/GroupMemberItem.vue b/im-ui/src/components/group/GroupMemberItem.vue
new file mode 100644
index 0000000..1af7943
--- /dev/null
+++ b/im-ui/src/components/group/GroupMemberItem.vue
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
{{ member.aliasName }}
+
+
+
+
+
+
+
+
diff --git a/im-ui/src/components/group/GroupMemberSelector.vue b/im-ui/src/components/group/GroupMemberSelector.vue
new file mode 100644
index 0000000..138d79b
--- /dev/null
+++ b/im-ui/src/components/group/GroupMemberSelector.vue
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
已勾选{{checkedMembers.length}}位成员
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/im-ui/src/components/rtc/RtcGroupVideo.vue b/im-ui/src/components/rtc/RtcGroupVideo.vue
new file mode 100644
index 0000000..ef83b3c
--- /dev/null
+++ b/im-ui/src/components/rtc/RtcGroupVideo.vue
@@ -0,0 +1,42 @@
+
+
+
+
+ 多人音视频通话为付费功能,有需要请联系作者...
+
+
+ 点击下方文档了解详细信息:
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
From 9adc57750e63498c52562a4eaaebcb9f2aa69f94 Mon Sep 17 00:00:00 2001
From: xsx <825657193@qq.com>
Date: Sun, 16 Jun 2024 15:07:05 +0800
Subject: [PATCH 10/18] =?UTF-8?q?feat:=20=E5=A4=9A=E4=BA=BA=E9=9F=B3?=
=?UTF-8?q?=E8=A7=86=E9=A2=91=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../group-rtc-join/group-rtc-join.vue | 89 +++++++++++++++++++
im-uniapp/store/chatStore.js | 2 -
im-uniapp/store/configStore.js | 32 +++++++
3 files changed, 121 insertions(+), 2 deletions(-)
create mode 100644 im-uniapp/components/group-rtc-join/group-rtc-join.vue
create mode 100644 im-uniapp/store/configStore.js
diff --git a/im-uniapp/components/group-rtc-join/group-rtc-join.vue b/im-uniapp/components/group-rtc-join/group-rtc-join.vue
new file mode 100644
index 0000000..0c0081f
--- /dev/null
+++ b/im-uniapp/components/group-rtc-join/group-rtc-join.vue
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
{{rtcInfo.userInfos.length+'人正在通话中'}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/im-uniapp/store/chatStore.js b/im-uniapp/store/chatStore.js
index 75950af..5356df3 100644
--- a/im-uniapp/store/chatStore.js
+++ b/im-uniapp/store/chatStore.js
@@ -51,7 +51,6 @@ export default {
}
})
})
- console.log(cacheChats.length)
},
openChat(state, chatInfo) {
let chats = this.getters.findChats();
@@ -295,7 +294,6 @@ export default {
});
// 将消息一次性装载回来
state.chats = cacheChats;
- console.log(cacheChats.length)
this.commit("saveToStorage");
},
saveToStorage(state) {
diff --git a/im-uniapp/store/configStore.js b/im-uniapp/store/configStore.js
new file mode 100644
index 0000000..ba289c2
--- /dev/null
+++ b/im-uniapp/store/configStore.js
@@ -0,0 +1,32 @@
+import http from '../common/request'
+
+export default {
+ state: {
+ webrtc: {}
+ },
+ mutations: {
+ setConfig(state, config) {
+ state.webrtc = config.webrtc;
+ },
+ clear(state){
+ state.webrtc = {};
+ }
+ },
+ actions:{
+ loadConfig(context){
+ return new Promise((resolve, reject) => {
+ http({
+ url: '/system/config',
+ method: 'GET'
+ }).then((config) => {
+ console.log("系统配置",config)
+ context.commit("setConfig",config);
+ resolve();
+ }).catch((res)=>{
+ reject(res);
+ });
+ })
+ }
+ }
+
+}
\ No newline at end of file
From be45e9ede4bebfb03cbe341b5093f4abe6ed1616 Mon Sep 17 00:00:00 2001
From: xsx <825657193@qq.com>
Date: Sun, 16 Jun 2024 15:58:30 +0800
Subject: [PATCH 11/18] =?UTF-8?q?feat:=20=E5=A4=9A=E4=BA=BA=E9=9F=B3?=
=?UTF-8?q?=E8=A7=86=E9=A2=91=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../service/impl/WebrtcGroupServiceImpl.java | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcGroupServiceImpl.java b/im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcGroupServiceImpl.java
index 423cefc..c5a2635 100644
--- a/im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcGroupServiceImpl.java
+++ b/im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcGroupServiceImpl.java
@@ -81,8 +81,8 @@ public class WebrtcGroupServiceImpl implements IWebrtcGroupService {
List busyUserIds = new LinkedList<>();
for (WebrtcUserInfo userInfo : dto.getUserInfos()) {
if (!imClient.isOnline(userInfo.getId())) {
- userInfos.add(userInfo);
- //offlineUserIds.add(userInfo.getId());
+ //userInfos.add(userInfo);
+ offlineUserIds.add(userInfo.getId());
} else if (userStateUtils.isBusy(userInfo.getId())) {
busyUserIds.add(userInfo.getId());
} else {
@@ -266,9 +266,9 @@ public class WebrtcGroupServiceImpl implements IWebrtcGroupService {
continue;
}
if (!imClient.isOnline(userInfo.getId())) {
- // offlineUserIds.add(userInfo.getId());
- userStateUtils.setBusy(userInfo.getId());
- newUserInfos.add(userInfo);
+ offlineUserIds.add(userInfo.getId());
+// userStateUtils.setBusy(userInfo.getId());
+// newUserInfos.add(userInfo);
} else if (userStateUtils.isBusy(userInfo.getId())) {
busyUserIds.add(userInfo.getId());
} else {
From 378afb827840665c8ac1d5bbae5793a146e955c4 Mon Sep 17 00:00:00 2001
From: xsx <825657193@qq.com>
Date: Sun, 16 Jun 2024 19:30:50 +0800
Subject: [PATCH 12/18] =?UTF-8?q?feat:=20=E5=A4=9A=E4=BA=BA=E9=9F=B3?=
=?UTF-8?q?=E8=A7=86=E9=A2=91=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../com/bx/imcommon/model/IMUserInfo.java | 2 +-
.../bx/implatform/annotation/OnlineCheck.java | 16 +++++++
.../implatform/aspect/OnlineCheckAspect.java | 43 +++++++++++++++++++
.../bx/implatform/config/RedissonConfig.java | 2 +-
.../controller/WebrtcGroupController.java | 2 +-
.../controller/WebrtcPrivateController.java | 2 +
.../implatform/dto/WebrtcGroupAnswerDTO.java | 2 +-
.../dto/WebrtcGroupCandidateDTO.java | 2 +-
.../implatform/dto/WebrtcGroupDeviceDTO.java | 2 +-
.../implatform/dto/WebrtcGroupFailedDTO.java | 2 +-
.../implatform/dto/WebrtcGroupInviteDTO.java | 2 +-
.../bx/implatform/dto/WebrtcGroupJoinDTO.java | 2 +-
.../implatform/dto/WebrtcGroupOfferDTO.java | 2 +-
.../implatform/dto/WebrtcGroupSetupDTO.java | 2 +-
.../com/bx/implatform/enums/WebrtcMode.java | 2 +-
.../service/impl/WebrtcGroupServiceImpl.java | 4 ++
.../session/WebrtcGroupSession.java | 2 +-
.../bx/implatform/session/WebrtcUserInfo.java | 2 +-
.../bx/implatform/util/UserStateUtils.java | 2 +-
.../bx/implatform/vo/OnlineTerminalVO.java | 2 +-
.../bx/implatform/vo/WebrtcGroupFailedVO.java | 2 +-
.../bx/implatform/vo/WebrtcGroupInfoVO.java | 2 +-
im-uniapp/manifest.json | 2 +-
23 files changed, 84 insertions(+), 19 deletions(-)
create mode 100644 im-platform/src/main/java/com/bx/implatform/annotation/OnlineCheck.java
create mode 100644 im-platform/src/main/java/com/bx/implatform/aspect/OnlineCheckAspect.java
diff --git a/im-commom/src/main/java/com/bx/imcommon/model/IMUserInfo.java b/im-commom/src/main/java/com/bx/imcommon/model/IMUserInfo.java
index a25cd0f..680cda6 100644
--- a/im-commom/src/main/java/com/bx/imcommon/model/IMUserInfo.java
+++ b/im-commom/src/main/java/com/bx/imcommon/model/IMUserInfo.java
@@ -5,7 +5,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2023-09-24 09:23:11
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/annotation/OnlineCheck.java b/im-platform/src/main/java/com/bx/implatform/annotation/OnlineCheck.java
new file mode 100644
index 0000000..f616002
--- /dev/null
+++ b/im-platform/src/main/java/com/bx/implatform/annotation/OnlineCheck.java
@@ -0,0 +1,16 @@
+package com.bx.implatform.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 在线校验,标注此注解的接口用户必须保持长连接,否则将抛异常
+ */
+@Retention(RetentionPolicy.RUNTIME)//运行时生效
+@Target(ElementType.METHOD)//作用在方法上
+public @interface OnlineCheck {
+
+}
diff --git a/im-platform/src/main/java/com/bx/implatform/aspect/OnlineCheckAspect.java b/im-platform/src/main/java/com/bx/implatform/aspect/OnlineCheckAspect.java
new file mode 100644
index 0000000..b81124c
--- /dev/null
+++ b/im-platform/src/main/java/com/bx/implatform/aspect/OnlineCheckAspect.java
@@ -0,0 +1,43 @@
+package com.bx.implatform.aspect;
+
+import cn.hutool.core.util.StrUtil;
+import com.bx.imclient.IMClient;
+import com.bx.implatform.annotation.RedisLock;
+import com.bx.implatform.exception.GlobalException;
+import com.bx.implatform.session.SessionContext;
+import com.bx.implatform.session.UserSession;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.redisson.api.RLock;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author: blue
+ * @date: 2024-06-16
+ * @version: 1.0
+ */
+@Slf4j
+@Aspect
+@Component
+@RequiredArgsConstructor
+public class OnlineCheckAspect {
+
+ private final IMClient imClient;
+
+ @Around("@annotation(com.bx.implatform.annotation.OnlineCheck)")
+ public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
+ UserSession session = SessionContext.getSession();
+ if(!imClient.isOnline(session.getUserId())){
+ throw new GlobalException("您当前的网络连接已断开,请稍后重试");
+ }
+ return joinPoint.proceed();
+ }
+
+}
diff --git a/im-platform/src/main/java/com/bx/implatform/config/RedissonConfig.java b/im-platform/src/main/java/com/bx/implatform/config/RedissonConfig.java
index 6e7dc87..7dc1c92 100644
--- a/im-platform/src/main/java/com/bx/implatform/config/RedissonConfig.java
+++ b/im-platform/src/main/java/com/bx/implatform/config/RedissonConfig.java
@@ -13,7 +13,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-09
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/controller/WebrtcGroupController.java b/im-platform/src/main/java/com/bx/implatform/controller/WebrtcGroupController.java
index 03361be..c9fb6b7 100644
--- a/im-platform/src/main/java/com/bx/implatform/controller/WebrtcGroupController.java
+++ b/im-platform/src/main/java/com/bx/implatform/controller/WebrtcGroupController.java
@@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-01
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/controller/WebrtcPrivateController.java b/im-platform/src/main/java/com/bx/implatform/controller/WebrtcPrivateController.java
index 40cca08..7d583c6 100644
--- a/im-platform/src/main/java/com/bx/implatform/controller/WebrtcPrivateController.java
+++ b/im-platform/src/main/java/com/bx/implatform/controller/WebrtcPrivateController.java
@@ -1,5 +1,6 @@
package com.bx.implatform.controller;
+import com.bx.implatform.annotation.OnlineCheck;
import com.bx.implatform.config.ICEServer;
import com.bx.implatform.result.Result;
import com.bx.implatform.result.ResultUtils;
@@ -19,6 +20,7 @@ public class WebrtcPrivateController {
private final IWebrtcPrivateService webrtcPrivateService;
+ @OnlineCheck
@ApiOperation(httpMethod = "POST", value = "呼叫视频通话")
@PostMapping("/call")
public Result call(@RequestParam Long uid, @RequestParam(defaultValue = "video") String mode, @RequestBody String offer) {
diff --git a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupAnswerDTO.java b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupAnswerDTO.java
index 3f98c4f..b66e68e 100644
--- a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupAnswerDTO.java
+++ b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupAnswerDTO.java
@@ -8,7 +8,7 @@ import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-01
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupCandidateDTO.java b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupCandidateDTO.java
index 93cda08..fd04e94 100644
--- a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupCandidateDTO.java
+++ b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupCandidateDTO.java
@@ -9,7 +9,7 @@ import javax.validation.constraints.NotNull;
import java.util.List;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-01
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupDeviceDTO.java b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupDeviceDTO.java
index bc8ec79..5d87b4d 100644
--- a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupDeviceDTO.java
+++ b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupDeviceDTO.java
@@ -8,7 +8,7 @@ import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-01
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupFailedDTO.java b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupFailedDTO.java
index e9fa69f..3df2cb9 100644
--- a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupFailedDTO.java
+++ b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupFailedDTO.java
@@ -7,7 +7,7 @@ import lombok.Data;
import javax.validation.constraints.NotNull;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-01
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupInviteDTO.java b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupInviteDTO.java
index e5ea7b8..7719a39 100644
--- a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupInviteDTO.java
+++ b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupInviteDTO.java
@@ -10,7 +10,7 @@ import javax.validation.constraints.NotNull;
import java.util.List;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-01
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupJoinDTO.java b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupJoinDTO.java
index 6d4e212..adbc066 100644
--- a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupJoinDTO.java
+++ b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupJoinDTO.java
@@ -8,7 +8,7 @@ import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-01
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupOfferDTO.java b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupOfferDTO.java
index fbf9de5..057fe20 100644
--- a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupOfferDTO.java
+++ b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupOfferDTO.java
@@ -8,7 +8,7 @@ import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-01
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupSetupDTO.java b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupSetupDTO.java
index 9736bba..f59989f 100644
--- a/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupSetupDTO.java
+++ b/im-platform/src/main/java/com/bx/implatform/dto/WebrtcGroupSetupDTO.java
@@ -10,7 +10,7 @@ import javax.validation.constraints.NotNull;
import java.util.List;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-01
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/enums/WebrtcMode.java b/im-platform/src/main/java/com/bx/implatform/enums/WebrtcMode.java
index 1aa50de..ebaf099 100644
--- a/im-platform/src/main/java/com/bx/implatform/enums/WebrtcMode.java
+++ b/im-platform/src/main/java/com/bx/implatform/enums/WebrtcMode.java
@@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-01
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcGroupServiceImpl.java b/im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcGroupServiceImpl.java
index c5a2635..8851b32 100644
--- a/im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcGroupServiceImpl.java
+++ b/im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcGroupServiceImpl.java
@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSON;
import com.bx.imclient.IMClient;
import com.bx.imcommon.model.IMGroupMessage;
import com.bx.imcommon.model.IMUserInfo;
+import com.bx.implatform.annotation.OnlineCheck;
import com.bx.implatform.annotation.RedisLock;
import com.bx.implatform.config.WebrtcConfig;
import com.bx.implatform.contant.RedisKey;
@@ -55,6 +56,7 @@ public class WebrtcGroupServiceImpl implements IWebrtcGroupService {
private final WebrtcConfig webrtcConfig;
+ @OnlineCheck
@RedisLock(prefixKey = RedisKey.IM_LOCK_RTC_GROUP, key = "#dto.groupId")
@Override
public void setup(WebrtcGroupSetupDTO dto) {
@@ -200,6 +202,7 @@ public class WebrtcGroupServiceImpl implements IWebrtcGroupService {
log.info("群通话失败,userId:{},groupId:{},原因:{}", userSession.getUserId(), dto.getReason());
}
+ @OnlineCheck
@RedisLock(prefixKey = RedisKey.IM_LOCK_RTC_GROUP, key = "#groupId")
@Override
public void join(Long groupId) {
@@ -239,6 +242,7 @@ public class WebrtcGroupServiceImpl implements IWebrtcGroupService {
log.info("加入群通话,userId:{},groupId:{}", userSession.getUserId(), groupId);
}
+ @OnlineCheck
@RedisLock(prefixKey = RedisKey.IM_LOCK_RTC_GROUP, key = "#dto.groupId")
@Override
public void invite(WebrtcGroupInviteDTO dto) {
diff --git a/im-platform/src/main/java/com/bx/implatform/session/WebrtcGroupSession.java b/im-platform/src/main/java/com/bx/implatform/session/WebrtcGroupSession.java
index f6343bf..098c724 100644
--- a/im-platform/src/main/java/com/bx/implatform/session/WebrtcGroupSession.java
+++ b/im-platform/src/main/java/com/bx/implatform/session/WebrtcGroupSession.java
@@ -7,7 +7,7 @@ import java.util.LinkedList;
import java.util.List;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-01
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/session/WebrtcUserInfo.java b/im-platform/src/main/java/com/bx/implatform/session/WebrtcUserInfo.java
index 75b16fb..5bae898 100644
--- a/im-platform/src/main/java/com/bx/implatform/session/WebrtcUserInfo.java
+++ b/im-platform/src/main/java/com/bx/implatform/session/WebrtcUserInfo.java
@@ -5,7 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-02
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/util/UserStateUtils.java b/im-platform/src/main/java/com/bx/implatform/util/UserStateUtils.java
index 40678b2..567737e 100644
--- a/im-platform/src/main/java/com/bx/implatform/util/UserStateUtils.java
+++ b/im-platform/src/main/java/com/bx/implatform/util/UserStateUtils.java
@@ -10,7 +10,7 @@ import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-10
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/vo/OnlineTerminalVO.java b/im-platform/src/main/java/com/bx/implatform/vo/OnlineTerminalVO.java
index 4aed6c1..67e5413 100644
--- a/im-platform/src/main/java/com/bx/implatform/vo/OnlineTerminalVO.java
+++ b/im-platform/src/main/java/com/bx/implatform/vo/OnlineTerminalVO.java
@@ -7,7 +7,7 @@ import lombok.Data;
import java.util.List;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2023-10-28 21:17:59
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/vo/WebrtcGroupFailedVO.java b/im-platform/src/main/java/com/bx/implatform/vo/WebrtcGroupFailedVO.java
index 78548b0..5c7b988 100644
--- a/im-platform/src/main/java/com/bx/implatform/vo/WebrtcGroupFailedVO.java
+++ b/im-platform/src/main/java/com/bx/implatform/vo/WebrtcGroupFailedVO.java
@@ -7,7 +7,7 @@ import lombok.Data;
import java.util.List;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-09
* @version: 1.0
*/
diff --git a/im-platform/src/main/java/com/bx/implatform/vo/WebrtcGroupInfoVO.java b/im-platform/src/main/java/com/bx/implatform/vo/WebrtcGroupInfoVO.java
index 8706b41..bf27527 100644
--- a/im-platform/src/main/java/com/bx/implatform/vo/WebrtcGroupInfoVO.java
+++ b/im-platform/src/main/java/com/bx/implatform/vo/WebrtcGroupInfoVO.java
@@ -8,7 +8,7 @@ import lombok.Data;
import java.util.List;
/**
- * @author: 谢绍许
+ * @author: Blue
* @date: 2024-06-09
* @version: 1.0
*/
diff --git a/im-uniapp/manifest.json b/im-uniapp/manifest.json
index e5d7646..d69c7ad 100644
--- a/im-uniapp/manifest.json
+++ b/im-uniapp/manifest.json
@@ -100,7 +100,7 @@
/* 小程序特有相关 */
"mp-weixin" : {
"appid" : "wxda94f40bfad0262c",
- "libVersion": "latest",
+ "libVersion" : "latest",
"setting" : {
"urlCheck" : false
},
From bde08d19092a8ea934ccc55ebbc28345555e987f Mon Sep 17 00:00:00 2001
From: xsx <825657193@qq.com>
Date: Mon, 17 Jun 2024 23:46:13 +0800
Subject: [PATCH 13/18] =?UTF-8?q?feat:=20=E7=A7=BB=E9=99=A4=E5=B0=8F?=
=?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=AE=A1=E6=A0=B8=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
im-ui/src/components/rtc/RtcGroupVideo.vue | 802 +++++++++++++++++-
im-uniapp/App.vue | 18 +-
.../components/user-search/user-search.vue | 118 ---
im-uniapp/pages.json | 2 +-
im-uniapp/pages/group/group.vue | 6 +-
5 files changed, 784 insertions(+), 162 deletions(-)
delete mode 100644 im-uniapp/components/user-search/user-search.vue
diff --git a/im-ui/src/components/rtc/RtcGroupVideo.vue b/im-ui/src/components/rtc/RtcGroupVideo.vue
index ef83b3c..83efc17 100644
--- a/im-ui/src/components/rtc/RtcGroupVideo.vue
+++ b/im-ui/src/components/rtc/RtcGroupVideo.vue
@@ -1,42 +1,802 @@
-
-
-
- 多人音视频通话为付费功能,有需要请联系作者...
+
+
+
-
- 点击下方文档了解详细信息:
-
-
-
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/im-uniapp/App.vue b/im-uniapp/App.vue
index a2ba339..41f6933 100644
--- a/im-uniapp/App.vue
+++ b/im-uniapp/App.vue
@@ -15,8 +15,6 @@
init() {
// 加载数据
store.dispatch("load").then(() => {
- // 审核
- this.initAudit();
// 初始化websocket
this.initWebSocket();
}).catch((e) => {
@@ -50,6 +48,7 @@
}
});
wsApi.onClose((res) => {
+ console.log("ws断开",res);
// 1000是客户端正常主动关闭
if (res.code != 1000) {
// 重新连接
@@ -278,21 +277,6 @@
return true;
}
return loginInfo.expireTime < new Date().getTime();
- },
- initAudit() {
- if (store.state.userStore.userInfo.type == 1) {
- // 显示群组功能
- uni.setTabBarItem({
- index: 2,
- text: "群聊"
- })
- } else {
- // 隐藏群组功能
- uni.setTabBarItem({
- index: 2,
- text: "搜索"
- })
- }
}
},
onLaunch() {
diff --git a/im-uniapp/components/user-search/user-search.vue b/im-uniapp/components/user-search/user-search.vue
deleted file mode 100644
index fadd7f6..0000000
--- a/im-uniapp/components/user-search/user-search.vue
+++ /dev/null
@@ -1,118 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- {{ user.nickName}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/im-uniapp/pages.json b/im-uniapp/pages.json
index c540831..4a4f870 100644
--- a/im-uniapp/pages.json
+++ b/im-uniapp/pages.json
@@ -63,7 +63,7 @@
"pagePath": "pages/group/group",
"iconPath": "static/tarbar/group.png",
"selectedIconPath": "static/tarbar/group_active.png",
- "text": "搜索"
+ "text": "群聊"
},
{
"pagePath": "pages/mine/mine",
diff --git a/im-uniapp/pages/group/group.vue b/im-uniapp/pages/group/group.vue
index a215665..19ba5a8 100644
--- a/im-uniapp/pages/group/group.vue
+++ b/im-uniapp/pages/group/group.vue
@@ -1,5 +1,5 @@
-
+
@@ -19,10 +19,6 @@
-
-
-
-
\ No newline at end of file
From e2404b148593450950be6afaf32794e451974b23 Mon Sep 17 00:00:00 2001
From: xsx <825657193@qq.com>
Date: Sat, 22 Jun 2024 11:41:25 +0800
Subject: [PATCH 18/18] =?UTF-8?q?feat:=20=E5=A4=9A=E4=BA=BA=E8=AF=AD?=
=?UTF-8?q?=E9=9F=B3=E9=80=9A=E8=AF=9D=E5=8A=9F=E8=83=BD=E4=B8=8A=E7=BA=BF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 1 -
im-ui/src/view/Login.vue | 27 ++++++---------------------
2 files changed, 6 insertions(+), 22 deletions(-)
diff --git a/README.md b/README.md
index d524d93..032bf40 100644
--- a/README.md
+++ b/README.md
@@ -255,6 +255,5 @@ wsApi.onClose((e) => {
1. 本系统允许用于商业用途,且不收费(自愿投币)。**但切记不要用于任何非法用途** ,本软件作者不会为此承担任何责任
1. 基于本系统二次开发后再次开源的项目,请注明引用出处,以避免引发不必要的误会
-1. 如果您也想体验开源(bei bai piao)的快感,成为本项目的贡献者,欢迎提交PR。开发前最好提前联系作者,避免功能重复开发
1. 作者目前不打算接项目,如果能接受1k/天以上的报价,也可以聊聊
diff --git a/im-ui/src/view/Login.vue b/im-ui/src/view/Login.vue
index 5e14eda..2ab0468 100644
--- a/im-ui/src/view/Login.vue
+++ b/im-ui/src/view/Login.vue
@@ -8,35 +8,20 @@
加入uniapp移动端,支持移动端和web端同时在线,多端消息同步
目前uniapp移动端支持安卓、ios、h5、微信小程序
聊天窗口支持粘贴截图、@群成员、已读未读显示
-
支持群聊已读显示(回执消息)
-
语雀文档
- 盒子IM详细介绍文档,目前限时免费开放中
+ 语雀文档:
+ 盒子IM详细介绍文档
-
最近更新(2024-03-17):
+
最近更新(2024-06-22):
- - web端音视频功能优化:支持语音呼叫、会话中加入通话状态消息
- - uniapp端支持音视频通话,并与web端打通
- - uniapp端音视频源码通话源码暂未开源,需付费获取:
- uniapp端音视频通源码购买说明
+
- 群语音通话功能上线,且同时支持web端和uniapp端
+ - 音视频通话部分源码未开源,可付费获取:
+ 音视频源码购买说明
-
-
-
最近更新(2024-04-27):
-
- - uniapp端加载离线消息慢以及卡顿问题优化
- - web端样式风格调整
-
-
如果本项目对您有帮助,请在gitee上帮忙点个star