diff --git a/im-platform/src/main/java/com/bx/implatform/controller/WebrtcController.java b/im-platform/src/main/java/com/bx/implatform/controller/WebrtcController.java index 2bd4d5d..d75ec6d 100644 --- a/im-platform/src/main/java/com/bx/implatform/controller/WebrtcController.java +++ b/im-platform/src/main/java/com/bx/implatform/controller/WebrtcController.java @@ -21,8 +21,8 @@ public class WebrtcController { @ApiOperation(httpMethod = "POST", value = "呼叫视频通话") @PostMapping("/call") - public Result call(@RequestParam Long uid, @RequestBody String offer) { - webrtcService.call(uid, offer); + public Result call(@RequestParam Long uid, @RequestParam(defaultValue = "video") String mode, @RequestBody String offer) { + webrtcService.call(uid, mode, offer); return ResultUtils.success(); } @@ -57,15 +57,15 @@ public class WebrtcController { @ApiOperation(httpMethod = "POST", value = "挂断") @PostMapping("/handup") - public Result leave(@RequestParam Long uid) { - webrtcService.leave(uid); + public Result handup(@RequestParam Long uid) { + webrtcService.handup(uid); return ResultUtils.success(); } @PostMapping("/candidate") @ApiOperation(httpMethod = "POST", value = "同步candidate") - public Result forwardCandidate(@RequestParam Long uid, @RequestBody String candidate) { + public Result candidate(@RequestParam Long uid, @RequestBody String candidate) { webrtcService.candidate(uid, candidate); return ResultUtils.success(); } diff --git a/im-platform/src/main/java/com/bx/implatform/enums/MessageType.java b/im-platform/src/main/java/com/bx/implatform/enums/MessageType.java index 1ca0784..2200387 100644 --- a/im-platform/src/main/java/com/bx/implatform/enums/MessageType.java +++ b/im-platform/src/main/java/com/bx/implatform/enums/MessageType.java @@ -53,10 +53,15 @@ public enum MessageType { * 消息加载标记 */ LOADDING(30,"加载中"), + + /** + * 语音呼叫 + */ + RTC_CALL_VOICE(100, "语音呼叫"), /** - * 呼叫 + * 视频呼叫 */ - RTC_CALL(101, "呼叫"), + RTC_CALL_VIDEO(101, "视频呼叫"), /** * 接受 */ diff --git a/im-platform/src/main/java/com/bx/implatform/service/IWebrtcService.java b/im-platform/src/main/java/com/bx/implatform/service/IWebrtcService.java index 4e98a79..b93858f 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/IWebrtcService.java +++ b/im-platform/src/main/java/com/bx/implatform/service/IWebrtcService.java @@ -12,9 +12,9 @@ import java.util.List; */ public interface IWebrtcService { - void call(Long uid, String offer); + void call(Long uid, String mode,String offer); - void accept(Long uid, @RequestBody String answer); + void accept(Long uid, String answer); void reject(Long uid); @@ -22,7 +22,7 @@ public interface IWebrtcService { void failed(Long uid, String reason); - void leave(Long uid); + void handup(Long uid); void candidate(Long uid, String candidate); diff --git a/im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcServiceImpl.java b/im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcServiceImpl.java index 5832e51..5b2ccad 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcServiceImpl.java +++ b/im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcServiceImpl.java @@ -33,7 +33,7 @@ public class WebrtcServiceImpl implements IWebrtcService { private final ICEServerConfig iceServerConfig; @Override - public void call(Long uid, String offer) { + public void call(Long uid, String mode, String offer) { UserSession session = SessionContext.getSession(); if (!imClient.isOnline(uid)) { throw new GlobalException("对方目前不在线"); @@ -46,7 +46,8 @@ public class WebrtcServiceImpl implements IWebrtcService { redisTemplate.opsForValue().set(key, webrtcSession, 12, TimeUnit.HOURS); // 向对方所有终端发起呼叫 PrivateMessageVO messageInfo = new PrivateMessageVO(); - messageInfo.setType(MessageType.RTC_CALL.code()); + MessageType messageType = mode.equals("video") ? MessageType.RTC_CALL_VIDEO : MessageType.RTC_CALL_VOICE; + messageInfo.setType(messageType.code()); messageInfo.setRecvId(uid); messageInfo.setSendId(session.getUserId()); messageInfo.setContent(offer); @@ -120,7 +121,7 @@ public class WebrtcServiceImpl implements IWebrtcService { removeWebrtcSession(session.getUserId(), uid); // 向对方所有终端推送取消通话信令 PrivateMessageVO messageInfo = new PrivateMessageVO(); - messageInfo.setType(MessageType.RTC_ACCEPT.code()); + messageInfo.setType(MessageType.RTC_CANCEL.code()); messageInfo.setRecvId(uid); messageInfo.setSendId(session.getUserId()); @@ -146,12 +147,12 @@ public class WebrtcServiceImpl implements IWebrtcService { messageInfo.setType(MessageType.RTC_FAILED.code()); messageInfo.setRecvId(uid); messageInfo.setSendId(session.getUserId()); + messageInfo.setContent(reason); IMPrivateMessage sendMessage = new IMPrivateMessage<>(); sendMessage.setSender(new IMUserInfo(session.getUserId(), session.getTerminal())); sendMessage.setRecvId(uid); - // 告知其他终端已经会话失败,中止呼叫 - sendMessage.setSendToSelf(true); + sendMessage.setSendToSelf(false); sendMessage.setSendResult(false); sendMessage.setRecvTerminals(Collections.singletonList(webrtcSession.getCallerTerminal())); sendMessage.setData(messageInfo); @@ -161,7 +162,7 @@ public class WebrtcServiceImpl implements IWebrtcService { } @Override - public void leave(Long uid) { + public void handup(Long uid) { UserSession session = SessionContext.getSession(); // 查询webrtc会话 WebrtcSession webrtcSession = getWebrtcSession(session.getUserId(), uid); @@ -215,9 +216,9 @@ public class WebrtcServiceImpl implements IWebrtcService { private WebrtcSession getWebrtcSession(Long userId, Long uid) { String key = getSessionKey(userId, uid); - WebrtcSession webrtcSession = (WebrtcSession) redisTemplate.opsForValue().get(key); + WebrtcSession webrtcSession = (WebrtcSession)redisTemplate.opsForValue().get(key); if (webrtcSession == null) { - throw new GlobalException("视频通话已结束"); + throw new GlobalException("通话已结束"); } return webrtcSession; } diff --git a/im-ui/src/api/enums.js b/im-ui/src/api/enums.js index 3206bba..0e6a1b1 100644 --- a/im-ui/src/api/enums.js +++ b/im-ui/src/api/enums.js @@ -5,13 +5,16 @@ const MESSAGE_TYPE = { 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: 101, + RTC_CALL_VOICE: 100, + RTC_CALL_VIDEO: 101, RTC_ACCEPT: 102, RTC_REJECT: 103, RTC_CANCEL: 104, @@ -20,10 +23,12 @@ const MESSAGE_TYPE = { RTC_CANDIDATE: 107 } -const USER_STATE = { - OFFLINE: 0, - FREE: 1, - BUSY: 2 +const RTC_STATE = { + FREE: 0, //空闲,可以被呼叫 + WAIT_CALL: 1, // 呼叫后等待 + WAIT_ACCEPT: 2, // 被呼叫后等待 + ACCEPTED: 3, // 已接受聊天,等待建立连接 + CHATING:4 // 聊天中 } const TERMINAL_TYPE = { @@ -41,7 +46,7 @@ const MESSAGE_STATUS = { export { MESSAGE_TYPE, - USER_STATE, + RTC_STATE, TERMINAL_TYPE, MESSAGE_STATUS } diff --git a/im-ui/src/assets/audio/call.wav b/im-ui/src/assets/audio/call.wav index 754e33c..8eae87f 100644 Binary files a/im-ui/src/assets/audio/call.wav and b/im-ui/src/assets/audio/call.wav differ diff --git a/im-ui/src/assets/iconfont/iconfont.css b/im-ui/src/assets/iconfont/iconfont.css index 7092657..af7aa38 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=1706022894868') format('truetype'); + src: url('iconfont.ttf?t=1710567233281') format('truetype'); } .iconfont { @@ -11,6 +11,14 @@ -moz-osx-font-smoothing: grayscale; } +.icon-chat-video:before { + content: "\e73b"; +} + +.icon-chat-voice:before { + content: "\e633"; +} + .icon-ok:before { content: "\e6ac"; } diff --git a/im-ui/src/assets/iconfont/iconfont.ttf b/im-ui/src/assets/iconfont/iconfont.ttf index 79f6e9c..b1d7cb7 100644 Binary files a/im-ui/src/assets/iconfont/iconfont.ttf and b/im-ui/src/assets/iconfont/iconfont.ttf differ diff --git a/im-ui/src/components/chat/ChatBox.vue b/im-ui/src/components/chat/ChatBox.vue index 93af571..3d74536 100644 --- a/im-ui/src/components/chat/ChatBox.vue +++ b/im-ui/src/components/chat/ChatBox.vue @@ -13,7 +13,9 @@
-
+
+
+
@@ -133,13 +138,19 @@ export default { methods: { moveChatToTop(){ let chatIdx = this.$store.getters.findChatIdx(this.chat); - console.log(chatIdx); this.$store.commit("moveTop",chatIdx); }, closeRefBox() { this.$refs.emoBox.close(); this.$refs.atBox.close(); }, + onCall(type){ + if(type == this.$enums.MESSAGE_TYPE.RT_VOICE){ + this.showChatVideo('voice'); + }else if(type == this.$enums.MESSAGE_TYPE.RT_VIDEO){ + this.showChatVideo('video'); + } + }, onKeyDown() { if (this.$refs.atBox.show) { this.$refs.atBox.moveDown() @@ -433,11 +444,17 @@ export default { closeVoiceBox() { this.showVoice = false; }, - showVideoBox() { - this.$store.commit("showChatPrivateVideoBox", { + showChatVideo(mode) { + let rtcInfo = { + mode: mode, + isHost: true, friend: this.friend, - master: true - }); + sendId: this.$store.state.userStore.userInfo.id, + recvId: this.friend.id, + offer: "", + state: this.$enums.RTC_STATE.WAIT_CALL + } + this.$store.commit("setRtcInfo",rtcInfo); }, showHistoryBox() { this.showHistory = true; @@ -686,6 +703,12 @@ export default { }, unreadCount() { return this.chat.unreadCount; + }, + messageSize() { + if (!this.chat || !this.chat.messages) { + return 0; + } + return this.chat.messages.length; } }, watch: { @@ -716,9 +739,9 @@ export default { }, immediate: true }, - unreadCount: { - handler(newCount, oldCount) { - if (newCount > 0) { + messageSize: { + handler(newSize, oldSize) { + if (newSize > oldSize) { // 拉至底部 this.scrollToBottom(); } @@ -812,7 +835,6 @@ export default { } } - .send-content-area { position: relative; display: flex; @@ -820,8 +842,6 @@ export default { height: 100%; background-color: white !important; - - .send-text-area { box-sizing: border-box; padding: 5px; diff --git a/im-ui/src/components/chat/ChatMessageItem.vue b/im-ui/src/components/chat/ChatMessageItem.vue index 22b0e6c..04ab953 100644 --- a/im-ui/src/components/chat/ChatMessageItem.vue +++ b/im-ui/src/components/chat/ChatMessageItem.vue @@ -1,6 +1,9 @@ \ No newline at end of file diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index 687bafd..445eaf7 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -1,13 +1,12 @@