From 7b37c4dca59af3973212ebc60f87bfccaeb06c60 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Sun, 20 Nov 2022 21:26:23 +0800 Subject: [PATCH 01/28] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{IMServerMap.java => IMServerGroup.java} | 2 +- .../netty/processor/LoginProcessor.java | 4 ++-- .../imserver/netty/tcp/TcpSocketServer.java | 19 +++++++++++++------ .../bx/imserver/netty/ws/WebSocketServer.java | 19 +++++++++++++------ .../task/PullUnreadGroupMessageTask.java | 4 ++-- .../task/PullUnreadPrivateMessageTask.java | 4 ++-- 6 files changed, 33 insertions(+), 19 deletions(-) rename im-server/src/main/java/com/bx/imserver/netty/{IMServerMap.java => IMServerGroup.java} (94%) diff --git a/im-server/src/main/java/com/bx/imserver/netty/IMServerMap.java b/im-server/src/main/java/com/bx/imserver/netty/IMServerGroup.java similarity index 94% rename from im-server/src/main/java/com/bx/imserver/netty/IMServerMap.java rename to im-server/src/main/java/com/bx/imserver/netty/IMServerGroup.java index de6fff8..a740485 100644 --- a/im-server/src/main/java/com/bx/imserver/netty/IMServerMap.java +++ b/im-server/src/main/java/com/bx/imserver/netty/IMServerGroup.java @@ -12,7 +12,7 @@ import java.util.List; @Slf4j @Component -public class IMServerMap implements CommandLineRunner { +public class IMServerGroup implements CommandLineRunner { public static volatile long serverId = 0; diff --git a/im-server/src/main/java/com/bx/imserver/netty/processor/LoginProcessor.java b/im-server/src/main/java/com/bx/imserver/netty/processor/LoginProcessor.java index 0285779..2fdd903 100644 --- a/im-server/src/main/java/com/bx/imserver/netty/processor/LoginProcessor.java +++ b/im-server/src/main/java/com/bx/imserver/netty/processor/LoginProcessor.java @@ -6,7 +6,7 @@ import com.bx.imcommon.contant.RedisKey; import com.bx.imcommon.enums.IMCmdType; import com.bx.imcommon.model.IMSendInfo; import com.bx.imcommon.model.LoginInfo; -import com.bx.imserver.netty.IMServerMap; +import com.bx.imserver.netty.IMServerGroup; import com.bx.imserver.netty.UserChannelCtxMap; import com.bx.imserver.netty.ws.WebSocketServer; import io.netty.channel.ChannelHandlerContext; @@ -50,7 +50,7 @@ public class LoginProcessor extends MessageProcessor { ctx.channel().attr(attr).set(0L); // 在redis上记录每个user的channelId,15秒没有心跳,则自动过期 String key = RedisKey.IM_USER_SERVER_ID+loginInfo.getUserId(); - redisTemplate.opsForValue().set(key, IMServerMap.serverId, Constant.ONLINE_TIMEOUT_SECOND, TimeUnit.SECONDS); + redisTemplate.opsForValue().set(key, IMServerGroup.serverId, Constant.ONLINE_TIMEOUT_SECOND, TimeUnit.SECONDS); // 响应ws IMSendInfo sendInfo = new IMSendInfo(); sendInfo.setCmd(IMCmdType.LOGIN.code()); diff --git a/im-server/src/main/java/com/bx/imserver/netty/tcp/TcpSocketServer.java b/im-server/src/main/java/com/bx/imserver/netty/tcp/TcpSocketServer.java index 7270306..6143e4d 100644 --- a/im-server/src/main/java/com/bx/imserver/netty/tcp/TcpSocketServer.java +++ b/im-server/src/main/java/com/bx/imserver/netty/tcp/TcpSocketServer.java @@ -34,9 +34,9 @@ public class TcpSocketServer implements IMServer { @Value("${tcpsocket.port}") private int port; - private ServerBootstrap bootstrap = new ServerBootstrap(); - private EventLoopGroup bossGroup = new NioEventLoopGroup(); - private EventLoopGroup workGroup = new NioEventLoopGroup(); + private ServerBootstrap bootstrap; + private EventLoopGroup bossGroup; + private EventLoopGroup workGroup; @Override public boolean isReady() { @@ -45,6 +45,9 @@ public class TcpSocketServer implements IMServer { @Override public void start() { + bootstrap = new ServerBootstrap(); + bossGroup = new NioEventLoopGroup(); + workGroup = new NioEventLoopGroup(); // 设置为主从线程模型 bootstrap.group(bossGroup, workGroup) // 设置服务端NIO通信类型 @@ -84,10 +87,14 @@ public class TcpSocketServer implements IMServer { @Override public void stop(){ - log.info("tcp server 停止"); - bossGroup.shutdownGracefully(); - workGroup.shutdownGracefully(); + if(bossGroup != null && !bossGroup.isShuttingDown() && !bossGroup.isShutdown() ) { + bossGroup.shutdownGracefully(); + } + if(workGroup != null && !workGroup.isShuttingDown() && !workGroup.isShutdown() ) { + workGroup.shutdownGracefully(); + } this.ready = false; + log.info("tcp server 停止"); } diff --git a/im-server/src/main/java/com/bx/imserver/netty/ws/WebSocketServer.java b/im-server/src/main/java/com/bx/imserver/netty/ws/WebSocketServer.java index ffe8dc8..2d51ab8 100644 --- a/im-server/src/main/java/com/bx/imserver/netty/ws/WebSocketServer.java +++ b/im-server/src/main/java/com/bx/imserver/netty/ws/WebSocketServer.java @@ -37,9 +37,9 @@ public class WebSocketServer implements IMServer { private volatile boolean ready = false; - private ServerBootstrap bootstrap = new ServerBootstrap(); - private EventLoopGroup bossGroup = new NioEventLoopGroup(); - private EventLoopGroup workGroup = new NioEventLoopGroup(); + private ServerBootstrap bootstrap; + private EventLoopGroup bossGroup; + private EventLoopGroup workGroup; @Override @@ -49,6 +49,9 @@ public class WebSocketServer implements IMServer { @Override public void start() { + bootstrap = new ServerBootstrap(); + bossGroup = new NioEventLoopGroup(); + workGroup = new NioEventLoopGroup(); // 设置为主从线程模型 bootstrap.group(bossGroup, workGroup) // 设置服务端NIO通信类型 @@ -92,10 +95,14 @@ public class WebSocketServer implements IMServer { @Override public void stop() { - log.info("websocket server 停止"); - bossGroup.shutdownGracefully(); - workGroup.shutdownGracefully(); + if(bossGroup != null && !bossGroup.isShuttingDown() && !bossGroup.isShutdown() ) { + bossGroup.shutdownGracefully(); + } + if(workGroup != null && !workGroup.isShuttingDown() && !workGroup.isShutdown() ) { + workGroup.shutdownGracefully(); + } this.ready = false; + log.info("websocket server 停止"); } diff --git a/im-server/src/main/java/com/bx/imserver/task/PullUnreadGroupMessageTask.java b/im-server/src/main/java/com/bx/imserver/task/PullUnreadGroupMessageTask.java index 7be78c6..3681c47 100644 --- a/im-server/src/main/java/com/bx/imserver/task/PullUnreadGroupMessageTask.java +++ b/im-server/src/main/java/com/bx/imserver/task/PullUnreadGroupMessageTask.java @@ -4,7 +4,7 @@ import com.bx.imcommon.contant.RedisKey; import com.bx.imcommon.enums.IMCmdType; import com.bx.imcommon.model.GroupMessageInfo; import com.bx.imcommon.model.IMRecvInfo; -import com.bx.imserver.netty.IMServerMap; +import com.bx.imserver.netty.IMServerGroup; import com.bx.imserver.netty.processor.MessageProcessor; import com.bx.imserver.netty.processor.ProcessorFactory; import com.bx.imserver.netty.ws.WebSocketServer; @@ -30,7 +30,7 @@ public class PullUnreadGroupMessageTask extends AbstractPullMessageTask { @Override public void pullMessage() { // 从redis拉取未读消息 - String key = RedisKey.IM_UNREAD_GROUP_QUEUE + IMServerMap.serverId; + String key = RedisKey.IM_UNREAD_GROUP_QUEUE + IMServerGroup.serverId; List messageInfos = redisTemplate.opsForList().range(key,0,-1); for(Object o: messageInfos){ redisTemplate.opsForList().leftPop(key); diff --git a/im-server/src/main/java/com/bx/imserver/task/PullUnreadPrivateMessageTask.java b/im-server/src/main/java/com/bx/imserver/task/PullUnreadPrivateMessageTask.java index 071033b..50bb8b2 100644 --- a/im-server/src/main/java/com/bx/imserver/task/PullUnreadPrivateMessageTask.java +++ b/im-server/src/main/java/com/bx/imserver/task/PullUnreadPrivateMessageTask.java @@ -5,7 +5,7 @@ import com.bx.imcommon.contant.RedisKey; import com.bx.imcommon.enums.IMCmdType; import com.bx.imcommon.model.IMRecvInfo; import com.bx.imcommon.model.PrivateMessageInfo; -import com.bx.imserver.netty.IMServerMap; +import com.bx.imserver.netty.IMServerGroup; import com.bx.imserver.netty.processor.MessageProcessor; import com.bx.imserver.netty.processor.ProcessorFactory; import com.bx.imserver.netty.ws.WebSocketServer; @@ -30,7 +30,7 @@ public class PullUnreadPrivateMessageTask extends AbstractPullMessageTask { @Override public void pullMessage() { // 从redis拉取未读消息 - String key = RedisKey.IM_UNREAD_PRIVATE_QUEUE + IMServerMap.serverId; + String key = RedisKey.IM_UNREAD_PRIVATE_QUEUE + IMServerGroup.serverId; List messageInfos = redisTemplate.opsForList().range(key,0,-1); for(Object o: messageInfos){ redisTemplate.opsForList().leftPop(key); From d0e6d52ec07365328ca235f948bf5c0c93c72ea7 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Sun, 20 Nov 2022 23:41:14 +0800 Subject: [PATCH 02/28] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/api/wssocket.js | 8 ++++---- im-ui/src/view/Home.vue | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/im-ui/src/api/wssocket.js b/im-ui/src/api/wssocket.js index 0bf7300..f860a9a 100644 --- a/im-ui/src/api/wssocket.js +++ b/im-ui/src/api/wssocket.js @@ -19,20 +19,20 @@ let initWebSocket = () => { hasLogin = false; websock = new WebSocket(wsurl); websock.onmessage = function(e) { - let msg = JSON.parse(e.data) - if (msg.cmd == 0) { + let sendInfo = JSON.parse(e.data) + if (sendInfo.cmd == 0) { hasLogin = true; heartCheck.start() console.log('WebSocket登录成功') // 登录成功才算连接完成 openCallBack && openCallBack(); } - else if(msg.cmd==1){ + else if(sendInfo.cmd==1){ // 重新开启心跳定时 heartCheck.reset(); } else { // 其他消息转发出去 - messageCallBack && messageCallBack(JSON.parse(e.data)) + messageCallBack && messageCallBack(sendInfo.cmd,sendInfo.data) } } websock.onclose = function(e) { diff --git a/im-ui/src/view/Home.vue b/im-ui/src/view/Home.vue index 4bc2a62..86b836e 100644 --- a/im-ui/src/view/Home.vue +++ b/im-ui/src/view/Home.vue @@ -67,20 +67,20 @@ this.$wsApi.onopen(() => { this.pullUnreadMessage(); }); - this.$wsApi.onmessage((e) => { - if (e.cmd == 2) { + this.$wsApi.onmessage((cmd,msgInfo) => { + if (cmd == 2) { // 异地登录,强制下线 this.$message.error("您已在其他地方登陆,将被强制下线"); setTimeout(() => { location.href = "/"; }, 1000) - } else if (e.cmd == 3) { + } else if (cmd == 3) { // 插入私聊消息 - this.handlePrivateMessage(e.data); - } else if (e.cmd == 4) { + this.handlePrivateMessage(msgInfo); + } else if (cmd == 4) { // 插入群聊消息 - this.handleGroupMessage(e.data); + this.handleGroupMessage(msgInfo); } }) }, From 0e3a0ee0cdf674e80e3f85eea2bcfdb5ef4e7355 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Mon, 21 Nov 2022 16:21:47 +0800 Subject: [PATCH 03/28] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/bx/imserver/netty/IMServerGroup.java | 14 ++++++++++++++ .../bx/imserver/task/AbstractPullMessageTask.java | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/im-server/src/main/java/com/bx/imserver/netty/IMServerGroup.java b/im-server/src/main/java/com/bx/imserver/netty/IMServerGroup.java index a740485..60c640e 100644 --- a/im-server/src/main/java/com/bx/imserver/netty/IMServerGroup.java +++ b/im-server/src/main/java/com/bx/imserver/netty/IMServerGroup.java @@ -22,6 +22,20 @@ public class IMServerGroup implements CommandLineRunner { @Autowired private List imServers; + /*** + * 判断服务器是否就绪 + * + * @return + **/ + public boolean isReady(){ + for(IMServer imServer:imServers){ + if(!imServer.isReady()){ + return false; + } + } + return true; + } + @Override public void run(String... args) throws Exception { // 初始化SERVER_ID diff --git a/im-server/src/main/java/com/bx/imserver/task/AbstractPullMessageTask.java b/im-server/src/main/java/com/bx/imserver/task/AbstractPullMessageTask.java index ea4625a..d5dafe4 100644 --- a/im-server/src/main/java/com/bx/imserver/task/AbstractPullMessageTask.java +++ b/im-server/src/main/java/com/bx/imserver/task/AbstractPullMessageTask.java @@ -1,6 +1,6 @@ package com.bx.imserver.task; -import com.bx.imserver.netty.ws.WebSocketServer; +import com.bx.imserver.netty.IMServerGroup; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -17,7 +17,7 @@ public abstract class AbstractPullMessageTask{ private ExecutorService executorService; @Autowired - private WebSocketServer WSServer; + private IMServerGroup serverGroup; public AbstractPullMessageTask(){ this.threadNum = 1; @@ -38,7 +38,7 @@ public abstract class AbstractPullMessageTask{ @Override public void run() { try{ - if(WSServer.isReady()){ + if(serverGroup.isReady()){ pullMessage(); } Thread.sleep(100); From a85449358c4b675886b88a256bf0aeea0e932ca4 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Tue, 22 Nov 2022 16:06:36 +0800 Subject: [PATCH 04/28] =?UTF-8?q?=E5=9F=9F=E5=90=8D=E5=A4=87=E6=A1=88?= =?UTF-8?q?=E7=BB=88=E4=BA=8E=E9=80=9A=E8=BF=87=EF=BC=8C=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E5=9F=9F=E5=90=8D=E8=AE=BF=E9=97=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/.env.production | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/im-ui/.env.production b/im-ui/.env.production index f372106..5b75d44 100644 --- a/im-ui/.env.production +++ b/im-ui/.env.production @@ -3,6 +3,6 @@ ENV = 'production' # app名称 VUE_APP_NAME = "盒子IM" # 接口地址 -VUE_APP_BASE_API = 'https://8.134.92.70:443/api' +VUE_APP_BASE_API = 'https://www.boxim.online/api' # ws地址 -VUE_APP_WS_URL = 'wss://8.134.92.70:81/im' \ No newline at end of file +VUE_APP_WS_URL = 'wss://www.boxim.online:81/im' \ No newline at end of file From 802acad69758c01b8403dd25fef0825b07252240 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Tue, 22 Nov 2022 16:34:49 +0800 Subject: [PATCH 05/28] =?UTF-8?q?=E8=B0=83=E8=AF=95=E6=89=8B=E6=9C=BA?= =?UTF-8?q?=E7=AB=AF=E5=BD=95=E9=9F=B3=E5=A4=B1=E8=B4=A5=E7=9A=84=E5=8E=9F?= =?UTF-8?q?=E5=9B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/components/chat/ChatVoice.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/im-ui/src/components/chat/ChatVoice.vue b/im-ui/src/components/chat/ChatVoice.vue index 223eb49..9bb7363 100644 --- a/im-ui/src/components/chat/ChatVoice.vue +++ b/im-ui/src/components/chat/ChatVoice.vue @@ -61,7 +61,8 @@ this.state = 'RUNNING'; this.stateTip = "正在录音..."; }).catch(error => { - this.$message.error("录音失败"); + console.log(error); + this.$message.error(error); console.log(error); }); From 1e9bc06b7b189bdd11398cd6246965dfa91f451c Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Wed, 23 Nov 2022 18:13:39 +0800 Subject: [PATCH 06/28] =?UTF-8?q?=E8=B0=83=E8=AF=95=E6=89=8B=E6=9C=BA?= =?UTF-8?q?=E7=AB=AF=E5=BD=95=E9=9F=B3=E5=A4=B1=E8=B4=A5=E7=9A=84=E5=8E=9F?= =?UTF-8?q?=E5=9B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/GroupMessageServiceImpl.java | 6 ++++ .../processor/GroupMessageProcessor.java | 28 +++++++++---------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java b/im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java index 2b5769c..d24c9df 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java +++ b/im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java @@ -74,6 +74,8 @@ public class GroupMessageServiceImpl extends ServiceImpluserId!=id).collect(Collectors.toList()); // 群发 GroupMessageInfo msgInfo = BeanUtils.copyProperties(msg, GroupMessageInfo.class); imClient.sendGroupMessage(userIds,msgInfo); @@ -112,6 +114,8 @@ public class GroupMessageServiceImpl extends ServiceImpl userIds = groupMemberService.findUserIdsByGroupId(msg.getGroupId()); + // 不用发给自己 + userIds = userIds.stream().filter(uid->userId.equals(uid)).collect(Collectors.toList()); GroupMessageInfo msgInfo = BeanUtils.copyProperties(msg, GroupMessageInfo.class); msgInfo.setType(MessageType.TIP.code()); String content = String.format("'%s'撤回了一条消息",member.getAliasName()); @@ -140,6 +144,7 @@ public class GroupMessageServiceImpl extends ServiceImpl wrapper = new QueryWrapper(); wrapper.lambda().eq(GroupMessage::getGroupId,member.getGroupId()) .gt(GroupMessage::getSendTime,member.getCreatedTime()) + .ne(GroupMessage::getSendId, userId) .ne(GroupMessage::getStatus, MessageStatus.RECALL.code()); if(maxReadedId!=null){ wrapper.lambda().gt(GroupMessage::getId,maxReadedId); @@ -198,4 +203,5 @@ public class GroupMessageServiceImpl extends ServiceImpl Date: Fri, 25 Nov 2022 11:26:17 +0800 Subject: [PATCH 07/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/bx/imclient/sender/IMSender.java | 8 +- .../{IMSendStatus.java => IMSendCode.java} | 8 +- .../com/bx/imcommon/model/SendResult.java | 9 +- .../controller/WebrtcController.java | 118 ++++++++++++++++++ .../com/bx/implatform/enums/MessageType.java | 10 +- .../listener/GroupMessageListener.java | 4 +- .../listener/PrivateMessageListener.java | 29 ++++- .../processor/GroupMessageProcessor.java | 10 +- .../processor/PrivateMessageProcessor.java | 10 +- im-ui/src/assets/iconfont/iconfont.css | 16 ++- im-ui/src/assets/iconfont/iconfont.ttf | Bin 3464 -> 3928 bytes im-ui/src/assets/iconfont/iconfont.woff | Bin 2260 -> 2572 bytes im-ui/src/assets/iconfont/iconfont.woff2 | Bin 1864 -> 2096 bytes im-ui/src/components/chat/ChatBox.vue | 56 +++++---- im-ui/src/components/chat/ChatVoice.vue | 1 - im-ui/src/main.js | 4 +- im-ui/src/store/uiStore.js | 30 ++++- im-ui/src/store/userStore.js | 12 +- im-ui/src/view/Home.vue | 40 +++++- 19 files changed, 290 insertions(+), 75 deletions(-) rename im-commom/src/main/java/com/bx/imcommon/enums/{IMSendStatus.java => IMSendCode.java} (61%) create mode 100644 im-platform/src/main/java/com/bx/implatform/controller/WebrtcController.java diff --git a/im-client/src/main/java/com/bx/imclient/sender/IMSender.java b/im-client/src/main/java/com/bx/imclient/sender/IMSender.java index 9aa66d2..460dfa7 100644 --- a/im-client/src/main/java/com/bx/imclient/sender/IMSender.java +++ b/im-client/src/main/java/com/bx/imclient/sender/IMSender.java @@ -4,7 +4,7 @@ import com.bx.imclient.listener.MessageListenerMulticaster; import com.bx.imcommon.contant.RedisKey; import com.bx.imcommon.enums.IMCmdType; import com.bx.imcommon.enums.IMListenerType; -import com.bx.imcommon.enums.IMSendStatus; +import com.bx.imcommon.enums.IMSendCode; import com.bx.imcommon.model.GroupMessageInfo; import com.bx.imcommon.model.IMRecvInfo; import com.bx.imcommon.model.PrivateMessageInfo; @@ -54,8 +54,7 @@ public class IMSender { SendResult result = new SendResult(); result.setMessageInfo(messageInfo); result.setRecvId(recvId); - result.setStatus(IMSendStatus.FAIL); - result.setFailReason("用户不在线"); + result.setCode(IMSendCode.NOT_ONLINE); listenerMulticaster.multicast(IMListenerType.PRIVATE_MESSAGE, result); } } @@ -103,8 +102,7 @@ public class IMSender { SendResult result = new SendResult(); result.setMessageInfo(messageInfo); result.setRecvId(id); - result.setStatus(IMSendStatus.FAIL); - result.setFailReason("用户不在线"); + result.setCode(IMSendCode.NOT_ONLINE); listenerMulticaster.multicast(IMListenerType.GROUP_MESSAGE,result); } } diff --git a/im-commom/src/main/java/com/bx/imcommon/enums/IMSendStatus.java b/im-commom/src/main/java/com/bx/imcommon/enums/IMSendCode.java similarity index 61% rename from im-commom/src/main/java/com/bx/imcommon/enums/IMSendStatus.java rename to im-commom/src/main/java/com/bx/imcommon/enums/IMSendCode.java index cf82384..62ad254 100644 --- a/im-commom/src/main/java/com/bx/imcommon/enums/IMSendStatus.java +++ b/im-commom/src/main/java/com/bx/imcommon/enums/IMSendCode.java @@ -1,16 +1,18 @@ package com.bx.imcommon.enums; -public enum IMSendStatus { +public enum IMSendCode { SUCCESS(0,"发送成功"), - FAIL(1,"发送失败"); + NOT_ONLINE(1,"对方当前不在线"), + NOT_FIND_CHANNEL(2,"未找到对方的channel"), + UNKONW_ERROR(9999,"未知异常"); private int code; private String desc; // 构造方法 - IMSendStatus(int code, String desc) { + IMSendCode(int code, String desc) { this.code = code; this.desc = desc; } diff --git a/im-commom/src/main/java/com/bx/imcommon/model/SendResult.java b/im-commom/src/main/java/com/bx/imcommon/model/SendResult.java index 66ea316..2a65b82 100644 --- a/im-commom/src/main/java/com/bx/imcommon/model/SendResult.java +++ b/im-commom/src/main/java/com/bx/imcommon/model/SendResult.java @@ -1,6 +1,6 @@ package com.bx.imcommon.model; -import com.bx.imcommon.enums.IMSendStatus; +import com.bx.imcommon.enums.IMSendCode; import lombok.Data; @Data @@ -14,12 +14,7 @@ public class SendResult { /* * 发送状态 */ - private IMSendStatus status; - - /* - * 失败原因 - */ - private String failReason=""; + private IMSendCode code; /* * 消息体(透传) 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 new file mode 100644 index 0000000..75c6cc5 --- /dev/null +++ b/im-platform/src/main/java/com/bx/implatform/controller/WebrtcController.java @@ -0,0 +1,118 @@ +package com.bx.implatform.controller; + + +import com.bx.imclient.IMClient; +import com.bx.imcommon.model.PrivateMessageInfo; +import com.bx.implatform.enums.MessageType; +import com.bx.implatform.result.Result; +import com.bx.implatform.result.ResultUtils; +import com.bx.implatform.session.SessionContext; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +@Api(tags = "webrtc视频单人通话") +@RestController +@RequestMapping("/webrtc/private") +public class WebrtcController { + + @Autowired + private IMClient imClient; + + + @ApiOperation(httpMethod = "POST", value = "呼叫视频通话") + @PostMapping("/call") + public Result call(@RequestParam Long uid, @RequestBody String offer) { + Long userId = SessionContext.getSession().getId(); + + PrivateMessageInfo message = new PrivateMessageInfo(); + message.setType(MessageType.RTC_CALL.code()); + message.setRecvId(uid); + message.setSendId(userId); + message.setContent(offer); + imClient.sendPrivateMessage(uid,message); + return ResultUtils.success(); + } + + @ApiOperation(httpMethod = "POST", value = "接受视频通话") + @PostMapping("/accept") + public Result accept(@RequestParam Long uid,@RequestBody String answer) { + Long userId = SessionContext.getSession().getId(); + + PrivateMessageInfo message = new PrivateMessageInfo(); + message.setType(MessageType.RTC_ACCEPT.code()); + message.setRecvId(uid); + message.setSendId(userId); + message.setContent(answer); + imClient.sendPrivateMessage(uid,message); + return ResultUtils.success(); + } + + + @ApiOperation(httpMethod = "POST", value = "拒绝视频通话") + @PostMapping("/reject") + public Result reject(@RequestParam Long uid) { + Long userId = SessionContext.getSession().getId(); + PrivateMessageInfo message = new PrivateMessageInfo(); + message.setType(MessageType.RTC_REJECT.code()); + message.setRecvId(uid); + message.setSendId(userId); + imClient.sendPrivateMessage(uid,message); + return ResultUtils.success(); + } + + @ApiOperation(httpMethod = "POST", value = "取消呼叫") + @PostMapping("/cancel") + public Result cancel(@RequestParam Long uid) { + Long userId = SessionContext.getSession().getId(); + PrivateMessageInfo message = new PrivateMessageInfo(); + message.setType(MessageType.RTC_CANCEL.code()); + message.setRecvId(uid); + message.setSendId(userId); + imClient.sendPrivateMessage(uid,message); + return ResultUtils.success(); + } + + @ApiOperation(httpMethod = "POST", value = "呼叫失败") + @PostMapping("/failed") + public Result failed(@RequestParam Long uid,@RequestParam String reason) { + Long userId = SessionContext.getSession().getId(); + + PrivateMessageInfo message = new PrivateMessageInfo(); + message.setType(MessageType.RTC_FAILED.code()); + message.setRecvId(uid); + message.setSendId(userId); + message.setContent(reason); + imClient.sendPrivateMessage(uid,message); + return ResultUtils.success(); + } + + @ApiOperation(httpMethod = "POST", value = "挂断") + @PostMapping("/handup") + public Result leave(@RequestParam Long uid) { + Long userId = SessionContext.getSession().getId(); + + PrivateMessageInfo message = new PrivateMessageInfo(); + message.setType(MessageType.RTC_HANDUP.code()); + message.setRecvId(uid); + message.setSendId(userId); + imClient.sendPrivateMessage(uid,message); + return ResultUtils.success(); + } + + + @PostMapping("/candidate") + @ApiOperation(httpMethod = "POST", value = "同步candidate") + public Result candidate(@RequestParam Long uid,@RequestBody String candidate ) { + Long userId = SessionContext.getSession().getId(); + PrivateMessageInfo message = new PrivateMessageInfo(); + message.setType(MessageType.RTC_CANDIDATE.code()); + message.setRecvId(uid); + message.setSendId(userId); + message.setContent(candidate); + imClient.sendPrivateMessage(uid,message); + 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 f6a0622..cc7a07c 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 @@ -7,7 +7,15 @@ public enum MessageType { FILE(1,"文件"), IMAGE(2,"图片"), VIDEO(3,"视频"), - TIP(10,"系统提示"); + TIP(10,"系统提示"), + + RTC_CALL(101,"呼叫"), + RTC_ACCEPT(102,"接受"), + RTC_REJECT(103, "拒绝"), + RTC_CANCEL(104,"取消呼叫"), + RTC_FAILED(105,"呼叫失败"), + RTC_HANDUP(106,"挂断"), + RTC_CANDIDATE(107,"同步candidate"); private Integer code; diff --git a/im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java b/im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java index 3a8a745..1258781 100644 --- a/im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java +++ b/im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java @@ -3,7 +3,7 @@ package com.bx.implatform.listener; import com.bx.imclient.annotation.IMListener; import com.bx.imclient.listener.MessageListener; import com.bx.imcommon.enums.IMListenerType; -import com.bx.imcommon.enums.IMSendStatus; +import com.bx.imcommon.enums.IMSendCode; import com.bx.imcommon.model.GroupMessageInfo; import com.bx.imcommon.model.SendResult; import com.bx.implatform.contant.RedisKey; @@ -29,7 +29,7 @@ public class GroupMessageListener implements MessageListener { } // 保存该用户已拉取的最大消息id - if(result.getStatus().equals(IMSendStatus.SUCCESS)) { + if(result.getCode().equals(IMSendCode.SUCCESS)) { String key = RedisKey.IM_GROUP_READED_POSITION + messageInfo.getGroupId() + ":" + result.getRecvId(); redisTemplate.opsForValue().set(key, messageInfo.getId()); } diff --git a/im-platform/src/main/java/com/bx/implatform/listener/PrivateMessageListener.java b/im-platform/src/main/java/com/bx/implatform/listener/PrivateMessageListener.java index 636ee4e..b7fad41 100644 --- a/im-platform/src/main/java/com/bx/implatform/listener/PrivateMessageListener.java +++ b/im-platform/src/main/java/com/bx/implatform/listener/PrivateMessageListener.java @@ -1,10 +1,11 @@ package com.bx.implatform.listener; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.bx.imclient.IMClient; import com.bx.imclient.annotation.IMListener; import com.bx.imclient.listener.MessageListener; import com.bx.imcommon.enums.IMListenerType; -import com.bx.imcommon.enums.IMSendStatus; +import com.bx.imcommon.enums.IMSendCode; import com.bx.imcommon.model.PrivateMessageInfo; import com.bx.imcommon.model.SendResult; import com.bx.implatform.entity.PrivateMessage; @@ -14,6 +15,8 @@ import com.bx.implatform.service.IPrivateMessageService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import java.util.Date; + @Slf4j @IMListener(type = IMListenerType.PRIVATE_MESSAGE) @@ -22,15 +25,33 @@ public class PrivateMessageListener implements MessageListener { @Autowired private IPrivateMessageService privateMessageService; + @Autowired + private IMClient imClient; + @Override public void process(SendResult result){ PrivateMessageInfo messageInfo = (PrivateMessageInfo) result.getMessageInfo(); - if(messageInfo.getType().equals(MessageType.TIP)){ - // 提示类数据不记录 + // 提示类数据不记录 + if(messageInfo.getType().equals(MessageType.TIP.code())){ + return; } + // 视频通话信令不记录 + if(messageInfo.getType() >= MessageType.RTC_CALL.code() && messageInfo.getType()< MessageType.RTC_CANDIDATE.code()){ + // 通知用户呼叫失败了 + if(messageInfo.getType() == MessageType.RTC_CALL.code() + && !result.getCode().equals(IMSendCode.SUCCESS)){ + PrivateMessageInfo sendMessage = new PrivateMessageInfo(); + sendMessage.setRecvId(messageInfo.getSendId()); + sendMessage.setSendId(messageInfo.getRecvId()); + sendMessage.setType(MessageType.RTC_FAILED.code()); + sendMessage.setContent(result.getCode().description()); + sendMessage.setSendTime(new Date()); + imClient.sendPrivateMessage(sendMessage.getRecvId(),sendMessage); + } + } // 更新消息状态 - if(result.getStatus().equals(IMSendStatus.SUCCESS)){ + if(result.getCode().equals(IMSendCode.SUCCESS)){ UpdateWrapper updateWrapper = new UpdateWrapper<>(); updateWrapper.lambda().eq(PrivateMessage::getId,messageInfo.getId()) .eq(PrivateMessage::getStatus, MessageStatus.UNREAD.code()) diff --git a/im-server/src/main/java/com/bx/imserver/netty/processor/GroupMessageProcessor.java b/im-server/src/main/java/com/bx/imserver/netty/processor/GroupMessageProcessor.java index 2451779..3b589b9 100644 --- a/im-server/src/main/java/com/bx/imserver/netty/processor/GroupMessageProcessor.java +++ b/im-server/src/main/java/com/bx/imserver/netty/processor/GroupMessageProcessor.java @@ -2,7 +2,7 @@ package com.bx.imserver.netty.processor; import com.bx.imcommon.contant.RedisKey; import com.bx.imcommon.enums.IMCmdType; -import com.bx.imcommon.enums.IMSendStatus; +import com.bx.imcommon.enums.IMSendCode; import com.bx.imcommon.model.GroupMessageInfo; import com.bx.imcommon.model.IMRecvInfo; import com.bx.imcommon.model.IMSendInfo; @@ -43,7 +43,7 @@ public class GroupMessageProcessor extends MessageProcessor7-VibM$}YzRT)!nknZg1GUsv6ciA7syJ2w?$(#zL)#nx#xb~J(HPnzpI$@ zPM7xh0B{xn2BM=z!uR;n8~~@2d4@((gV~J-F97%+09lX6jEhyn&wDBN6Im!ug!F;k zB)m#i9Uo0j))Jt8TXfWpj7JTdY?-I}AorwK1j)X2G+w))MZSZTCj#K(!rIcGdvBHpHb}k2=0;}c%XSvB zYny$0djS7q%_VdkM5_CD=Y~NVM*xv}Gq8X}?}+9@?uYr5liar4lrWV)fuhuX-#|7O z*~$9s8qmWOrqE{JzU5lb+JGHAja%FdQ&|st#w*Kq{+>8Z()VWBXZjF290#Zgg+qbE z81PFfN}{U*UCwX_gJGf@Tuzs>9G#LVi2;9Zw_z~guad-a)QME7D&TKo-RC{DR??HH z^vXU;O{RCh`fA#{7P{JNe8_m!UR~qR1XkxYlHNK_D71ImHJ+iBe>-$~L9Ape&~|Cup6mvrZC3 zzXh77EXC8h=&Q<47YrT424}JEa*7&~x^O!wY-}K199)gZB5iGvSbY087}S(x)M#nd zlzv51IVLo_&oqSvRjNB;Raxg>x%r~q39A-qjSgP1YMS+Ey`%{(p?-IZBrr}bRL(9h vD%ZJU1vzBMqktkxD5C`xw3;Uh+RAN-`1n}t&_rxF7ES(gjA%5LNRqIhD+Rzh delta 433 zcmZurze_?<6#nk}t-Z?1AW%%JDVm!s$4c6Y#_FM_gD;I7Y!ZS%t>ML63YVbOC~ylQ z`U7feXtJi4K|_NzYUjSBsdG5@eCIpoJLf)!$^k1;%Ae!Zh;h_3i~A=)`r> z*@K<-UF!;v{D5+nNg2thjpbvSeWjSs5TUlj3gITjOvWq}!vskCK~FfFOBiZb{v##|*=|2n@eK!!qlMW|FNe712b$jp=M%T)VGjN7wP guo0JPO2g30!idHMCNhc1Okpb1n8)r8Ey%9m2e~a=t^fc4 diff --git a/im-ui/src/assets/iconfont/iconfont.woff b/im-ui/src/assets/iconfont/iconfont.woff index cbd67e381da698a1d1eabe89c93f4812061f8956..70cb16825918795a8dedc583de3d37bbab0b0d4a 100644 GIT binary patch delta 2086 zcmV+>2-)}45sVZRcTYw}00961000UM01E&B000kIkrX|D8cZW&ZDDW#00D>q005i- z00JN*rfZOAY@Wnp9h00+zf001ul001^3YQa%xXk}pl z00;a4000~S001Nh-UEwhZFG1500aBp*T000S~ z0001K0001w-OAE9lL!H40tu@QqX3`L)Vfsk{NB4cC`YBr(H z1PqZXb1;rDJx5C%r>a_PP^4an!`pR#Tp9@w)|`~MTE+y&zbb2Hl>%@?%=>+{WcZadW@Iqhj;C20W!5~TMN{GbO+j!Z2?bzyU`9ZZEI0m z2muxNH^=w=7b=wt{ZC_mk>x>_6;T#m#r8-e=RU?6gX7>FPiIgpHyyXcHR zKdvq={;;$J@@R39=zso#->YAyR<^F=hxLT{|LrHlPedf4D9WR5s4QgFN`4n+)et86 zcu|E)rmQ*Cm1R;MuLdi27BHzD7^fbN4rRxV9vve&+tBD!jB{gu!9XAgQ?lQus=iNh zrS|rcElWDu+RiJotdOJQ1YbM-`Ec%~?;hVb*S&DJemgsM@xu9whe*~oc=Gtf$vCD+ zu5|NV4GigpS6h|dvO-#{vNFzae_ z^=49WYP>+q$d-N3^p?Nzb&IDU$ZmxYhpeVUEj{ZuZlt0B3Zr;~Nu=oA={(-J@vI9qumR6g)hfuN zYW3P~0V9>KU&G>;c%hE)*sTZK2v@;?u5E6k2e)8b3VPK|@-vx*It)Ms%%%i)I?0;X z6B4T`hK~QPNDwP#HOvyEOirefP#wrHYnH=*v}vSvG6KJi^_A82jRsm>S>O6Ko~R6c zJXA@JK>GZfC&X zDh5P_7i=~M=j2;i4`;V?9=4Ttat^z|d&M@ibDmAINvd$3ebBxBkvtwIZZS>Uxl`bO zXJoi+DzqZiY+^x7p)1YL&mT=NEAyAm%yjq2`~)vc(4qDPj%fxhvFR>{M5?>iT3~D0 zA(wm3%)aiBWk){C%5=9r5$J~RqtwDr{soH#brt{sc${NkWME(b;t%%5?eY9JUm3Vr z7(n3u(tR5d^#2|f2Ie#%mxF-`BnkioM?MRJlivmxO#uK$5CU^}oMT~NU|=Bv0{{b< z04V?f00000)&TYaQ~~S)hyxA-Oart83IG6joMT{QU|`^4=w;w#00Aa2j|)it2lE*K z7)SxT006T;2SfpBiBS%MKnw-@P!OtD@l0l23zlHJZdem;j|uw6{LKtiw869wqrw44 z)M#)*iw=x4wRa8vRvWs-%c7Rl>QEl)JY+BF*6TDizb-Eyl|QagQdXNU>FFldEThD~ Qg!r8^(F)p?Ae#UH05Ex=O8@`> delta 1790 zcmVq004#n z00Hz=tp1>9YaBp*T000Pp z0000~0001SN{Nu0lL!H40`a_)aRC#5ZFUU8c%1E#F$%*l3`L*oG=`F)2kAvJXYbV0 zcFRM@rJwhd(K_AP8|A8}*#Z7dOo+P}g)YSCMrRg1a%~!SV+hC(r+vjaz zosQ#|@>QvAe%h6je(&{erfBT>*U-+#dn)c~;91xh$TzG8o}cZ3yky=2&vGGu@VwS3 zpu7O}vn_i70C=2@R84FfMHGIsWAA32-F5u8>&CGi+wr=I*N$WF4{2;Cts9gdT2dNF z|CF?)AwM*Vi4>`&Jp`qQ3RNH>B(6o3Do$Le5aL2BPDMhh#H|-XIdOy>dLbL$uA3@3 zfRNt2`R2Xxo1JeyKM(=UPY)&F!S*a6U_5NovERl4P7~XUa zy_1cE6Qo?)m3W#{RjEfUT3cDY?7yT z*7^PJHtnP$NRWaO4C2cot1kKdgi{iPmNFFuUoz*e@m)DK7mgUX%UT$+>clF4o6Jh3ySuvZ{zA2GH0A=R6j5X#z*5BEcAJ?Q{Q0lb~ zrv<-P5{%X%p{$oP&Mf<)qR-N542g&T|U zSaXb%u)e3w;~Q(Xl_uoq(Olt#7VHWR<#R?G6BUF2Un>ZIQsgsH@wS<&b_8?z*ZS3C zQF*doRH!5rs=f{Y*5&Iy^QWtoK^TX#u-4KGakP?2a}GOshrl>dac1Mlq(h4l(CZFA z2@(mkA~h5UDg`&G2+bjaDewL@((6rU9ARM4s92_)Bo@Xa8IHZVxygKZ>(=>FyHH!I zUBMyv1`?WomO$5ks{aZOEm^|A&U+$1z>BV9J`(woPZWJ6UbMetXb0Pu6~bf3UujQq zeX+<#iB@l*Q?1YnW1|a+YyPxWRs4VU1N^)d|Dl*k7VF~M>6cVZ~i843}x zHIE#q;sWO3fifJQ zKhjz-S^#*QV_;-pU;yH?qSCGL{5D@1xLFuL;Qs6;cLe?aAPWPtJ&?=6zyuNn02WFK z$pCnqV_;-pU~c%|z!1a200KagkpUHO002iu4gzs_oMT~NU|_+60RmtEApigX00000 z)&TYaQ~~S)hyxA-OaK6QoMT{QU|`^2=w;w#00AZ-<^nAP@w=85aaTXw2nm$y)6CH+;Gbs_pEqe&4%=hNlrv>s+5YD g5c{dD5bLv)G;Rn%eeVw0VQ<0WQbxRp9_wxv@AT6pxBvhE diff --git a/im-ui/src/assets/iconfont/iconfont.woff2 b/im-ui/src/assets/iconfont/iconfont.woff2 index 94a9411d6faf1bd3aa7de6af5230cbae4674791a..c78873999c9c332122ea4163cebe023b4e213402 100644 GIT binary patch delta 2092 zcmV+{2-Ek-4zLgycTYw#00961000Ou01E&B000kI000N#kr*9+gdhr#6peNPHUcCA zC<_(<1Rw>3X9s}~8(|F*RjkV(`#IpY!{a#_Dq~`z~q;CFy3H!slX%AV`CQv0<#b#B9HFXO$k+7X6caBZP zk%`)08z6u{?BY~^+wOe81xPL|-Q$<$_(icDd5Y45$IuWOfCF#@?f=$V6_HRxrx7Bx z{5$_MyN9T*SVOHsf(q>#Z4Q^_?I@W?XhceF=r)}mm&;a#K}&fqDRHGzczo?%f&d{+ z%!1vXn4S-o6IH$KAcc#&Ss>TTL{mc*m@8G-o>am2xzsCvEyx}?VAk0e0CwZ=m;cZr z=77ObaPQMopHK@&o=tg~$Dt-;&_@Uz%T2(e4d4I@)E%rwF8Z6!K~t=YS=eT^%mI*t zwenlo?0zHW(O_DYwC8^;VF!fSI8s7#pp?xH0xLo+~$*ltxl0!wrT) zC5p*+B9P_41%`Y*NrALoHyLxKyB{>@$@R;Zc?$Cj(4O-_+m%Kmt=ChAl;Y&8)VLb6 zVno`1w6KiEnnlLQ_1k``(TLJ(sI?e#72+eoDjiPE#ZDR=)hjWKncuFRCtP)mwfH*5 ztXHl>=Xngo29G^@2i060V^)h6o01sq0d1_S1f>N_IVctE#{&m|_~0y(!z_-{WJ-Dr z1~4@VOL?f1QVl>&=G9_{S`Cxs5JoyqqZ%Q9DFX`&Q)qYM1zy^o5Vopn-c{-49hwz_ z4bNQat68-|hi`q>k|6E8YG(cN`>dna0P$LW0V}T1P>jJ-M=ooGuryE2H+O?c}1f5qp6nflja@bk}r^^ct{bbnp%!ZeV(G*^xtH*~uM$ zXL1`C#Exo}AbYDJB~Poxch=4#>9BdIK~@_TRV!=wM9}WFQ4O+B$VdJ!@2m_j3k@v` zuYBO(aG@{#Ks(>riG5CRe)@UAInKCkURa(xvsjnAXNj`hY=gQ+X;)&qO{z_~U97E} zY5TS4cOj@un@bD}zRXMECutjxR%kMhoBWw~7lj8912{%sgo za=wpqXpuHa8z(<2!|l9#OsuFxSSVE3hpu*Gu{jrl+!^;jg9G=w|8C!E-`psFE_n62 zz%4JA%;ms@gZJkz^HKHnQNsk?aYWvb9xE;Huuc;C#9!b;=2j5GL7y)x@9;ww%Tk_d z?THyap6SV6-j+5FHkKaEUNd?{Tc4-#uJDrMWDD#ad1h8$KL3>&Pdu-iZeKK$5F}T= zcarDKG{5Q6m;uAA)W5u+T{Gi;`VTN2TJRU43x%!a$0C3|=z zd!=k52rl%cH)&k*aAQ$084y4Q7hNH!oD7JiuL$P+<2!$D$xrblgA?DZDQzmg-Vilt z=IhN(NvV7{e&t}&a1p<7C#divD58Q#>?7{C5 zGfRq{N1X>f^T@7Uqb>t~PJ>Pp4m=a;pz;A{m~D?sJW{X3+pgqUS5iGBeAGMSrhQPH z=L@2}0TJksUPLEABog9>G#Rmf8SLNyE=mmlE>T~W{!%-y?oaF;+FKn}84+F`Q8$2} zTZq2H{BH|=;|Et3C{i2auT?Gd!|tQSFmVKc z_Q$kU4lAI=%m5^R=u=Mpqx^`bNbq7u@fscUYlW5Ut2y@1w(Vu*p{+t^@`nYw3LgWq zgU=F%iA!3m8$#PQJLcjetG40Tj-@g5HUKBpmc>03v&l}*QOwSB4Iag)ZILBtA+jbH z%>yb#{-A}(-&{wYKXf7TKR49d-Q6M; zse3k^7!CaqP|;-Rli1%EURFn+&186vbLO3^MJ!mR2v5@UOb7&t zX*5dmK_qR9!nU20D~hXo%;-p1SOdLdNu-d8U0TXN?}g!iEP@UbLq8hWEZEV1P|1~q z&}TN0raXvsw&TwA|SO7j0|Nq<%S6Z$yVVlWvMLRUW^~L`~Pnm z_oKp$s915t6;FH#B$NpM*wH6W?&?U(5vRmwoOO#vx^_%UYAl9u-u7@4X~gRtp)!ea WlG`-UWHL4jZ^c!p=u}6etX2TL59%fW delta 1858 zcmV-I2fg^P5XcS~cTYw#00961000L_01E&B000e$000L2kr*9+gLDdw7>hIkHUcCA zAPW)z1Rw>3X9sZ`%?rqm)1@}xWzyyI|83fRGlR`QoMboVwRjyG;zp`*AjF0eQqiGx z*!8LkvZkc%epUbWkN^RU_wCo}8LFZ125*E&Ewg_=GP{V|i8VwwQ6XugU8A`-^OAXl zM5VOGLc4}Qtvcy{h1-AtV3B45D!;J29zH#-mOg}H5X>b&?Mix#hE_=RQZO@71kwVr z^jHSu8;AgECG`lv*ZKF8|B#Uspdg|VT%=lG(1B|n`Rh7b@Crcxf|MU_7;R4h5CNb8 z48JgTB7MHr2D+r-xn#$z88iX#3x6XGc;ucEkInOG@WU&AysquGj&5$js}Y6woJ-R-U!9;Nq%&se^^_k>p+Z#7H>m6DFME%n3s#VW_f7$8K9^AQOXmEW4+y5~0q}AoJ zIUItsBw43^)oSHx&etBYHuNGcSNj&%xPzyCQkRRh?GyHM_U90;WvyDL6xMUMoe`^d zbDVu+-`Wkqdv1`eFFE@`>j8G3t3YrLIp+vpwO+~D_l9hB7unZdAd6e4u(qH>aY-@O z?Af(WdHhjZWv<=OWPBJdP%`(=8h(pIo)+ts<@&-Ry6O|i( zGgTZJ9SO9?7t`KI50c0sw(Rq{Z)6bsw(zTMt(u* z$xl;3$iwE4@a|A!XlJ^9RYmN>xSZUODZvwi8{tv+#uAEtlo@A_`!XxzV%*BGp0KXY z&l=wR*AQD*tF5Kc6F&U?hdJZ*`tfsrBFxS?S8XWI4Q=B6ih@VvKT^Q|ObN}lzO0E) zm26d&{JS|ykyjp(Mu+OPfO!Y z#;8@Doho&QI>BO7b<9aNJ@P`-`=|?%is$6ilo4Go-ezMMWu>ZMN2G0(;14!xzL=d5j4$m%>~WxJsM~hR%x~+;%Q0Q zgCz^SL{~AW`RU7GAppR8oxVzE0|32(9u0Wk)1kBi0O-G|>q_k&>TSM%la(d_z<@IS z9c+io%CM!)zN(K>?k8fw?;95tQLFblgTwYoK>=d^<)Nq zK%&I}1b+4d1s|LT8h-A78W}$~h!AWL#PIV!u+S34`8Xujo@dszT67)JZL_0|?R=j; zDzN0f*6IucJ+0=UF0IboZ^Vx1^pv#jK#{IbXWrw0{uzc0i$x!;H}k#Gh3d_8Jw1H1 z$;@}@+AS%a7K>?IYN~$hfRuK=7kMy4hgMk9lpToHhS?d7Xa|pfKIqk!_Rp(@4h9UM z2dyv*joNB6`dK62qoqrcCNLJsKGCQb;@yuKFd&14s`ZGD$xPH+<`=rvI`o9SJffM# zx9Wlp?XVz4=Z0<*#z`fWUMf>gpWpj7uK-{XJcg7|geD9T5iyYvDUm_iW^CoB8~Y5h w+5Et4W1lIyfv9yMpu@ diff --git a/im-ui/src/components/chat/ChatBox.vue b/im-ui/src/components/chat/ChatBox.vue index 8228bce..c096cd1 100644 --- a/im-ui/src/components/chat/ChatBox.vue +++ b/im-ui/src/components/chat/ChatBox.vue @@ -2,8 +2,7 @@ {{title}} - + @@ -12,10 +11,8 @@
  • - +
@@ -26,24 +23,24 @@
-
- +
+
+
- +
发送
@@ -57,9 +54,7 @@
- +
@@ -70,8 +65,7 @@ import Emotion from "../common/Emotion.vue"; import ChatVoice from "./ChatVoice.vue"; import ChatHistory from "./ChatHistory.vue"; - - + export default { name: "chatPrivate", components: { @@ -129,7 +123,7 @@ thumbUrl: url } let msgInfo = { - id:0, + id: 0, fileId: file.uid, sendId: this.mine.id, content: JSON.stringify(data), @@ -218,10 +212,17 @@ closeVoiceBox() { this.showVoice = false; }, - showHistoryBox(){ + showVideoBox() { + console.log(this.friend) + this.$store.commit("showChatPrivateVideoBox", { + friend: this.friend, + master: true + }); + }, + showHistoryBox() { this.showHistory = true; }, - closeHistoryBox(){ + closeHistoryBox() { this.showHistory = false; }, handleSendVoice(data) { @@ -292,17 +293,17 @@ return false; } }, - deleteMessage(msgInfo){ - this.$confirm( '确认删除消息?','删除消息', { + deleteMessage(msgInfo) { + this.$confirm('确认删除消息?', '删除消息', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { - this.$store.commit("deleteMessage",msgInfo); + this.$store.commit("deleteMessage", msgInfo); }); }, - recallMessage(msgInfo){ - this.$confirm('确认撤回消息?','撤回消息', { + recallMessage(msgInfo) { + this.$confirm('确认撤回消息?', '撤回消息', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' @@ -316,10 +317,10 @@ msgInfo = JSON.parse(JSON.stringify(msgInfo)); msgInfo.type = 10; msgInfo.content = '你撤回了一条消息'; - this.$store.commit("insertMessage",msgInfo); + this.$store.commit("insertMessage", msgInfo); }) }); - + }, loadGroup(groupId) { this.$http({ @@ -346,6 +347,7 @@ method: 'get' }).then((friend) => { this.friend = friend; + console.log(this.friend) this.$store.commit("updateChatFromFriend", friend); this.$store.commit("updateFriend", friend); }) diff --git a/im-ui/src/components/chat/ChatVoice.vue b/im-ui/src/components/chat/ChatVoice.vue index 9bb7363..48bdc2c 100644 --- a/im-ui/src/components/chat/ChatVoice.vue +++ b/im-ui/src/components/chat/ChatVoice.vue @@ -19,7 +19,6 @@ 重新录音 立即发送 - diff --git a/im-ui/src/main.js b/im-ui/src/main.js index 5fb1b03..34478a3 100644 --- a/im-ui/src/main.js +++ b/im-ui/src/main.js @@ -9,7 +9,7 @@ import * as socketApi from './api/wssocket'; import emotion from './api/emotion.js'; import element from './api/element.js'; import store from './store'; - +import * as enums from './api/enums.js'; Vue.use(ElementUI); @@ -18,7 +18,7 @@ Vue.prototype.$wsApi = socketApi; Vue.prototype.$http = httpRequest // http请求方法 Vue.prototype.$emo = emotion; // emo表情 Vue.prototype.$elm = element; // 元素操作 - +Vue.prototype.$enums = enums; // 枚举 Vue.config.productionTip = false; new Vue({ diff --git a/im-ui/src/store/uiStore.js b/im-ui/src/store/uiStore.js index 351f6f4..1fd5d5a 100644 --- a/im-ui/src/store/uiStore.js +++ b/im-ui/src/store/uiStore.js @@ -11,6 +11,17 @@ export default { fullImage: { // 全屏大图 show: false, url: "" + }, + chatPrivateVideo:{ // 私人视频聊天 + show: false, + master: false, // 是否房主 + friend:{}, + offer:{} // 对方发起带过过来的sdp信息 + }, + videoAcceptor:{ // 视频呼叫选择 + show: false, + + friend:{} } }, @@ -35,6 +46,23 @@ export default { }, closeFullImageBox(state){ state.fullImage.show = false; + }, + showChatPrivateVideoBox(state,info){ + state.chatPrivateVideo.show = true; + state.chatPrivateVideo.friend = info.friend; + state.chatPrivateVideo.master = info.master; + state.chatPrivateVideo.offer = info.offer; + }, + closeChatPrivateVideoBox(state){ + state.chatPrivateVideo.show = false; + }, + showVideoAcceptorBox(state,friend){ + state.videoAcceptor.show = true; + state.videoAcceptor.friend = friend; + + }, + closeVideoAcceptorBox(state){ + state.videoAcceptor.show = false; } - }, + } } \ No newline at end of file diff --git a/im-ui/src/store/userStore.js b/im-ui/src/store/userStore.js index 4ad45bd..478ce8f 100644 --- a/im-ui/src/store/userStore.js +++ b/im-ui/src/store/userStore.js @@ -1,7 +1,12 @@ +import {USER_STATE} from "../api/enums.js" + export default { state: { - userInfo: {} + userInfo: { + + }, + state: USER_STATE.FREE }, mutations: { @@ -12,7 +17,10 @@ export default { this.commit("resetChatStore"); } state.userInfo = userInfo; - } + }, + setUserState(state, userState) { + state.state = userState; + }, } } \ No newline at end of file diff --git a/im-ui/src/view/Home.vue b/im-ui/src/view/Home.vue index 86b836e..6ff0632 100644 --- a/im-ui/src/view/Home.vue +++ b/im-ui/src/view/Home.vue @@ -38,6 +38,17 @@ + + + + @@ -46,17 +57,23 @@ import Setting from '../components/setting/Setting.vue'; import UserInfo from '../components/common/UserInfo.vue'; import FullImage from '../components/common/FullImage.vue'; - + import ChatPrivateVideo from '../components/chat/ChatPrivateVideo.vue'; + import VideoAcceptor from '../components/chat/VideoAcceptor.vue'; + + export default { components: { HeadImage, Setting, UserInfo, - FullImage + FullImage, + ChatPrivateVideo, + VideoAcceptor }, data() { return { - showSettingDialog: false + showSettingDialog: false, + } }, methods: { @@ -81,7 +98,7 @@ } else if (cmd == 4) { // 插入群聊消息 this.handleGroupMessage(msgInfo); - } + } }) }, pullUnreadMessage() { @@ -113,6 +130,21 @@ }) }, insertPrivateMessage(friend, msg) { + // webrtc 信令 + if(msg.type >= this.$enums.MESSAGE_TYPE.RTC_CALL + && msg.type <= this.$enums.MESSAGE_TYPE.RTC_CANDIDATE){ + // 呼叫 + console.log(msg) + if(msg.type == this.$enums.MESSAGE_TYPE.RTC_CALL + || msg.type == this.$enums.MESSAGE_TYPE.RTC_CANCEL){ + this.$store.commit("showVideoAcceptorBox",friend); + this.$refs.videoAcceptor.handleMessage(msg) + }else { + this.$refs.privateVideo.handleMessage(msg) + } + return ; + } + let chatInfo = { type: 'PRIVATE', targetId: friend.id, From c427d3c63d4e49b721ac8c42a76859b2296f0652 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 11:38:20 +0800 Subject: [PATCH 08/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/api/enums.js | 21 ++ im-ui/src/components/chat/ChatBox.vue | 2 +- .../src/components/chat/ChatPrivateVideo.vue | 322 ++++++++++++++++++ im-ui/src/components/chat/VideoAcceptor.vue | 124 +++++++ 4 files changed, 468 insertions(+), 1 deletion(-) create mode 100644 im-ui/src/api/enums.js create mode 100644 im-ui/src/components/chat/ChatPrivateVideo.vue create mode 100644 im-ui/src/components/chat/VideoAcceptor.vue diff --git a/im-ui/src/api/enums.js b/im-ui/src/api/enums.js new file mode 100644 index 0000000..ec05b4a --- /dev/null +++ b/im-ui/src/api/enums.js @@ -0,0 +1,21 @@ + +const MESSAGE_TYPE = { + RTC_CALL: 101, + RTC_ACCEPT: 102, + RTC_REJECT: 103, + RTC_CANCEL: 104, + RTC_FAILED: 105, + RTC_HANDUP: 106, + RTC_CANDIDATE: 107 +} + +const USER_STATE = { + OFFLINE: 0, + FREE: 1, + BUSY: 2 +} + +export { + MESSAGE_TYPE, + USER_STATE +} diff --git a/im-ui/src/components/chat/ChatBox.vue b/im-ui/src/components/chat/ChatBox.vue index c096cd1..d53e1f3 100644 --- a/im-ui/src/components/chat/ChatBox.vue +++ b/im-ui/src/components/chat/ChatBox.vue @@ -36,7 +36,7 @@
-
+
diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue new file mode 100644 index 0000000..87bcb3d --- /dev/null +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -0,0 +1,322 @@ + + + + + diff --git a/im-ui/src/components/chat/VideoAcceptor.vue b/im-ui/src/components/chat/VideoAcceptor.vue new file mode 100644 index 0000000..6db1e7e --- /dev/null +++ b/im-ui/src/components/chat/VideoAcceptor.vue @@ -0,0 +1,124 @@ + + + + + From d7456d9e71b67aeda54ee5fad192a78429da31c7 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 12:45:29 +0800 Subject: [PATCH 09/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/chat/ChatPrivateVideo.vue | 28 ++++++++++++++++--- im-ui/src/view/Home.vue | 1 + 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index 87bcb3d..f2eb838 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -53,9 +53,26 @@ "urls": navigator.mozGetUserMedia ? "stun:stun.services.mozilla.com" : navigator.webkitGetUserMedia ? "stun:stun.l.google.com:19302" : "stun:23.21.150.121" }, - { - urls: "stun:stun.l.google.com:19302" - } + {urls: "stun:stun.l.google.com:19302"}, + {urls: "stun:stun1.l.google.com:19302"}, + {urls: "stun:stun2.l.google.com:19302"}, + {urls: "stun:stun3.l.google.com:19302"}, + {urls: "stun:stun4.l.google.com:19302"}, + {urls: "stun:23.21.150.121"}, + {urls: "stun:stun01.sipphone.com"}, + {urls: "stun:stun.ekiga.net"}, + {urls: "stun:stun.fwdnet.net"}, + {urls: "stun:stun.ideasip.com"}, + {urls: "stun:stun.iptel.org"}, + {urls: "stun:stun.rixtelecom.se"}, + {urls: "stun:stun.schlund.de"}, + {urls: "stun:stunserver.org"}, + {urls: "stun:stun.softjoys.com"}, + {urls: "stun:stun.voiparound.com"}, + {urls: "stun:stun.voipbuster.com"}, + {urls: "stun:stun.voipstunt.com"}, + {urls: "stun:stun.voxgratia.org"}, + {urls: "stun:stun.xten.com"} ] } } @@ -102,10 +119,11 @@ }, closeCamera(){ if(this.stream){ + this.stream.getVideoTracks().forEach((track) =>{ track.stop(); - this.$refs.mineVideo.srcObject = null; }); + this.$refs.mineVideo.srcObject = null; this.stream = null; } @@ -205,6 +223,7 @@ method: 'post' }) this.close(); + this.$message.success("已挂断视频通话") }, cancel(){ this.$http({ @@ -212,6 +231,7 @@ method: 'post' }) this.close(); + this.$message.success("已停止呼叫视频通话") }, sendFailed(reason) { this.$http({ diff --git a/im-ui/src/view/Home.vue b/im-ui/src/view/Home.vue index 6ff0632..984dd87 100644 --- a/im-ui/src/view/Home.vue +++ b/im-ui/src/view/Home.vue @@ -79,6 +79,7 @@ methods: { init(userInfo) { this.$store.commit("setUserInfo", userInfo); + this.$store.commit("setUserState", this.$enums.USER_STATE.FREE); this.$store.commit("initStore"); this.$wsApi.createWebSocket(process.env.VUE_APP_WS_URL, userInfo.id); this.$wsApi.onopen(() => { From 198acdbaf5d2416780caa8b7dce49e22d0fb4235 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 14:45:51 +0800 Subject: [PATCH 10/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/components/chat/ChatPrivateVideo.vue | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index f2eb838..a67ea87 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -98,6 +98,11 @@ // 接受呼叫 this.accept(this.offer); } + + this.timerx && clearInterval(this.timerx); + this.timerx = setInterval(()=>{ + console.log(this.peerConnection.iceConnectionState); + },3000) }); }, @@ -130,9 +135,9 @@ }, setupPeerConnection(stream) { this.peerConnection = new RTCPeerConnection(this.configuration); - this.peerConnection.onaddstream = (e) => { + this.peerConnection.ontrack = (e) => { console.log("onaddstream") - this.$refs.friendVideo.srcObject = e.stream; + this.$refs.friendVideo.srcObject = e.streams[0]; }; this.peerConnection.onicecandidate = (event) => { if (event.candidate) { @@ -146,7 +151,9 @@ } } if (stream) { - this.peerConnection.addStream(stream); + stream.getTracks().forEach((track)=>{ + this.peerConnection.addTrack(track, stream); + }); } }, handleMessage(msg) { From 31d2d125228a44155408834f42ff213bcd36fa25 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 16:05:45 +0800 Subject: [PATCH 11/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/chat/ChatPrivateVideo.vue | 100 +++++++----------- 1 file changed, 41 insertions(+), 59 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index a67ea87..523a472 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -2,10 +2,7 @@
-
@@ -14,10 +11,12 @@
- -
-
- + +
+
+
@@ -50,30 +49,10 @@ candidates: [], configuration: { iceServers: [{ - "urls": navigator.mozGetUserMedia ? "stun:stun.services.mozilla.com" : navigator.webkitGetUserMedia ? - "stun:stun.l.google.com:19302" : "stun:23.21.150.121" - }, - {urls: "stun:stun.l.google.com:19302"}, - {urls: "stun:stun1.l.google.com:19302"}, - {urls: "stun:stun2.l.google.com:19302"}, - {urls: "stun:stun3.l.google.com:19302"}, - {urls: "stun:stun4.l.google.com:19302"}, - {urls: "stun:23.21.150.121"}, - {urls: "stun:stun01.sipphone.com"}, - {urls: "stun:stun.ekiga.net"}, - {urls: "stun:stun.fwdnet.net"}, - {urls: "stun:stun.ideasip.com"}, - {urls: "stun:stun.iptel.org"}, - {urls: "stun:stun.rixtelecom.se"}, - {urls: "stun:stun.schlund.de"}, - {urls: "stun:stunserver.org"}, - {urls: "stun:stun.softjoys.com"}, - {urls: "stun:stun.voiparound.com"}, - {urls: "stun:stun.voipbuster.com"}, - {urls: "stun:stun.voipstunt.com"}, - {urls: "stun:stun.voxgratia.org"}, - {urls: "stun:stun.xten.com"} - ] + 'urls': 'turn:www.boxim.online:3478', + 'credential': "admin", + 'username': "admin123" + }] } } }, @@ -98,11 +77,11 @@ // 接受呼叫 this.accept(this.offer); } - + this.timerx && clearInterval(this.timerx); - this.timerx = setInterval(()=>{ + this.timerx = setInterval(() => { console.log(this.peerConnection.iceConnectionState); - },3000) + }, 3000) }); }, @@ -122,16 +101,16 @@ callback() }); }, - closeCamera(){ - if(this.stream){ - - this.stream.getVideoTracks().forEach((track) =>{ + closeCamera() { + if (this.stream) { + + this.stream.getVideoTracks().forEach((track) => { track.stop(); - }); - this.$refs.mineVideo.srcObject = null; - this.stream = null; + }); + this.$refs.mineVideo.srcObject = null; + this.stream = null; } - + }, setupPeerConnection(stream) { this.peerConnection = new RTCPeerConnection(this.configuration); @@ -141,20 +120,21 @@ }; this.peerConnection.onicecandidate = (event) => { if (event.candidate) { - if(this.state == 'CONNECTED'){ + if (this.state == 'CONNECTED') { // 已连接,直接发送 this.sendCandidate(event.candidate); - }else{ + } else { // 未连接,缓存起来,连接后再发送 this.candidates.push(event.candidate) } } } if (stream) { - stream.getTracks().forEach((track)=>{ - this.peerConnection.addTrack(track, stream); - }); + stream.getTracks().forEach((track) => { + this.peerConnection.addTrack(track, stream); + }); } + this.peerConnection.IceConnectionStateChange }, handleMessage(msg) { if (msg.type == this.$enums.MESSAGE_TYPE.RTC_ACCEPT) { @@ -198,7 +178,7 @@ url: `/webrtc/private/call?uid=${this.friend.id}`, method: 'post', data: offer - }).then(()=>{ + }).then(() => { this.loading = true; this.state = 'CONNECTING'; }); @@ -217,7 +197,7 @@ method: 'post', data: answer }) - this.state='CONNECTED'; + this.state = 'CONNECTED'; }, (error) => { this.$message.error(error); @@ -232,7 +212,7 @@ this.close(); this.$message.success("已挂断视频通话") }, - cancel(){ + cancel() { this.$http({ url: `/webrtc/private/cancel?uid=${this.friend.id}`, method: 'post' @@ -259,19 +239,19 @@ this.loading = false; this.state = 'NOT_CONNECTED'; this.candidates = []; - this.$store.commit("setUserState",this.$enums.USER_STATE.FREE); + this.$store.commit("setUserState", this.$enums.USER_STATE.FREE); this.$refs.friendVideo.srcObject = null; this.peerConnection.close(); this.peerConnection.onicecandidate = null; this.peerConnection.onaddstream = null; - + }, - handleClose(){ - if(this.state=='CONNECTED'){ + handleClose() { + if (this.state == 'CONNECTED') { this.handup() - }else if(this.state == 'CONNECTING'){ + } else if (this.state == 'CONNECTING') { this.cancel(); - }else{ + } else { this.close(); } }, @@ -293,7 +273,7 @@ if (newValue) { this.init(); // 用户忙状态 - this.$store.commit("setUserState",this.$enums.USER_STATE.BUSY); + this.$store.commit("setUserState", this.$enums.USER_STATE.BUSY); console.log(this.$store.state.userStore.state) } } @@ -317,6 +297,7 @@ .chat-video-friend { height: 600px; + video { width: 100%; height: 100%; @@ -335,11 +316,12 @@ } } } - + .chat-video-controllbar { display: flex; justify-content: space-around; padding: 10px; + .icon { font-size: 50px; cursor: pointer; From 81be2ad41f1daedca60b0924361870ebcf38c116 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 16:15:15 +0800 Subject: [PATCH 12/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/components/chat/ChatPrivateVideo.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index 523a472..02dd2d9 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -50,8 +50,8 @@ configuration: { iceServers: [{ 'urls': 'turn:www.boxim.online:3478', - 'credential': "admin", - 'username': "admin123" + 'credential': "admin123", + 'username': "admin" }] } } From b51b9ee943a247f4a53b1ede2c0096134297abf8 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 16:24:08 +0800 Subject: [PATCH 13/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/components/chat/ChatPrivateVideo.vue | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index 02dd2d9..d036654 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -48,8 +48,10 @@ state: 'NOT_CONNECTED', candidates: [], configuration: { - iceServers: [{ - 'urls': 'turn:www.boxim.online:3478', + iceServers: [ + { 'url': 'stun:stun.l.google.com:19302' }, + { + 'url': 'turn:www.boxim.online:3478', 'credential': "admin123", 'username': "admin" }] From f11055c67dcfff42d432ef205f2e662846a0a243 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 16:28:20 +0800 Subject: [PATCH 14/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/components/chat/ChatPrivateVideo.vue | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index d036654..9d9430c 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -48,13 +48,16 @@ state: 'NOT_CONNECTED', candidates: [], configuration: { - iceServers: [ - { 'url': 'stun:stun.l.google.com:19302' }, - { - 'url': 'turn:www.boxim.online:3478', - 'credential': "admin123", - 'username': "admin" - }] + iceServers: { + iceServers: [ + { + 'url': 'turn:www.boxim.online:3478', + 'credential': "admin123", + 'username': "admin" + } + ], + sdpSemantics: 'plan-b' + } } } }, From dae362c97811a0423fd907d0350fdd6f8e3e1495 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 16:30:02 +0800 Subject: [PATCH 15/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/components/chat/ChatPrivateVideo.vue | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index 9d9430c..b3a0613 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -48,16 +48,12 @@ state: 'NOT_CONNECTED', candidates: [], configuration: { - iceServers: { - iceServers: [ - { - 'url': 'turn:www.boxim.online:3478', - 'credential': "admin123", - 'username': "admin" - } - ], - sdpSemantics: 'plan-b' - } + iceServers: [{ + 'url': 'turn:www.boxim.online:3478', + 'credential': "admin123", + 'username': "admin" + }], + sdpSemantics: 'plan-b' } } }, From e26d61b26fc94623b3c85194d8e9f4aa8ffab09b Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 16:43:15 +0800 Subject: [PATCH 16/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/components/chat/ChatPrivateVideo.vue | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index b3a0613..c63f6ad 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -48,12 +48,7 @@ state: 'NOT_CONNECTED', candidates: [], configuration: { - iceServers: [{ - 'url': 'turn:www.boxim.online:3478', - 'credential': "admin123", - 'username': "admin" - }], - sdpSemantics: 'plan-b' + } } }, From 57d85508dae69e36e4e6bd1fccf97017cec2d04a Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 16:49:04 +0800 Subject: [PATCH 17/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/components/chat/ChatPrivateVideo.vue | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index c63f6ad..7fc652d 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -48,7 +48,11 @@ state: 'NOT_CONNECTED', candidates: [], configuration: { - + iceServers: [{ + 'urls': 'turn:www.boxim.online:3478', + 'credential': "admin123", + 'username': "admin" + }] } } }, @@ -134,6 +138,8 @@ }, handleMessage(msg) { if (msg.type == this.$enums.MESSAGE_TYPE.RTC_ACCEPT) { + console.log("接收answer") + console.log(msg.content) this.peerConnection.setRemoteDescription(new RTCSessionDescription(JSON.parse(msg.content))); // 关闭等待提示 this.loading = false; @@ -170,6 +176,8 @@ call() { this.peerConnection.createOffer((offer) => { this.peerConnection.setLocalDescription(offer); + console.log("发送offer") + console.log(offer) this.$http({ url: `/webrtc/private/call?uid=${this.friend.id}`, method: 'post', @@ -185,8 +193,12 @@ }, accept(offer) { + console.log("接收到offer") + console.log(offer) this.peerConnection.setRemoteDescription(new RTCSessionDescription(offer)); this.peerConnection.createAnswer((answer) => { + console.log("发送answer") + console.log(answer) this.peerConnection.setLocalDescription(answer); this.$http({ url: `/webrtc/private/accept?uid=${this.friend.id}`, From a38adc0db88a22c46975bf2eecd55f125ed3f111 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 17:01:13 +0800 Subject: [PATCH 18/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/components/chat/ChatPrivateVideo.vue | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index 7fc652d..7e84ce1 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -49,9 +49,9 @@ candidates: [], configuration: { iceServers: [{ - 'urls': 'turn:www.boxim.online:3478', - 'credential': "admin123", - 'username': "admin" + 'url': 'turn:www.boxim.online:3478', + 'credential': 'admin123', + 'username': 'admin' }] } } @@ -177,11 +177,11 @@ this.peerConnection.createOffer((offer) => { this.peerConnection.setLocalDescription(offer); console.log("发送offer") - console.log(offer) + console.log(JSON.stringify(offer)) this.$http({ url: `/webrtc/private/call?uid=${this.friend.id}`, method: 'post', - data: offer + data: JSON.stringify(offer) }).then(() => { this.loading = true; this.state = 'CONNECTING'; @@ -198,12 +198,12 @@ this.peerConnection.setRemoteDescription(new RTCSessionDescription(offer)); this.peerConnection.createAnswer((answer) => { console.log("发送answer") - console.log(answer) + console.log(JSON.stringify(answer)) this.peerConnection.setLocalDescription(answer); this.$http({ url: `/webrtc/private/accept?uid=${this.friend.id}`, method: 'post', - data: answer + data: JSON.stringify(answer) }) this.state = 'CONNECTED'; }, @@ -238,7 +238,7 @@ this.$http({ url: `/webrtc/private/candidate?uid=${this.friend.id}`, method: 'post', - data: candidate + data: JSON.stringify(candidate) }) }, close() { From ba8f5071684ec1e921fcc9eccdef77a45c8548bb Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 19:00:11 +0800 Subject: [PATCH 19/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/chat/ChatPrivateVideo.vue | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index 7e84ce1..6d2dfa8 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -49,10 +49,27 @@ candidates: [], configuration: { iceServers: [{ - 'url': 'turn:www.boxim.online:3478', - 'credential': 'admin123', - 'username': 'admin' - }] + 'url': 'turn:www.boxim.online:3478', + 'credential': 'admin123', + 'username': 'admin' + }, + { + url: 'stun:stun.l.google.com:19302' + }, + { + url: 'stun:stun.anyfirewall.com:3478' + }, + { + url: 'turn:turn.bistri.com:80', + credential: 'homeo', + username: 'homeo' + }, + { + url: 'turn:turn.anyfirewall.com:443?transport=tcp', + credential: 'webrtc', + username: 'webrtc' + } + ] } } }, @@ -134,7 +151,10 @@ this.peerConnection.addTrack(track, stream); }); } - this.peerConnection.IceConnectionStateChange + this.peerConnection.oniceconnectionstatechange = function(event) { + console.log("ICE connection status changed : " + event.target.iceConnectionState) + }; + }, handleMessage(msg) { if (msg.type == this.$enums.MESSAGE_TYPE.RTC_ACCEPT) { From cb5a41cd86031c587e52f0aa71067c0d710103ed Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 19:08:41 +0800 Subject: [PATCH 20/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/components/chat/ChatPrivateVideo.vue | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index 6d2dfa8..67c543f 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -49,6 +49,11 @@ candidates: [], configuration: { iceServers: [{ + 'url': 'stun:www.boxim.online:3478', + 'credential': 'admin123', + 'username': 'admin' + }, + { 'url': 'turn:www.boxim.online:3478', 'credential': 'admin123', 'username': 'admin' From 7ec6f103efdd1fc31321231633d6ba7a63c1a1bf Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 19:57:41 +0800 Subject: [PATCH 21/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/chat/ChatPrivateVideo.vue | 25 +++---------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index 67c543f..3fdd33f 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -48,31 +48,14 @@ state: 'NOT_CONNECTED', candidates: [], configuration: { - iceServers: [{ - 'url': 'stun:www.boxim.online:3478', - 'credential': 'admin123', - 'username': 'admin' - }, - { - 'url': 'turn:www.boxim.online:3478', - 'credential': 'admin123', - 'username': 'admin' - }, + iceServers: [ { url: 'stun:stun.l.google.com:19302' }, { - url: 'stun:stun.anyfirewall.com:3478' - }, - { - url: 'turn:turn.bistri.com:80', - credential: 'homeo', - username: 'homeo' - }, - { - url: 'turn:turn.anyfirewall.com:443?transport=tcp', - credential: 'webrtc', - username: 'webrtc' + url: 'turn:www.boxim.online:3478', + credential: 'admin123', + username: 'admin' } ] } From 9f2e13f9c4f04bc492d457bc698417bad75cb23f Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 22:47:20 +0800 Subject: [PATCH 22/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/components/chat/ChatPrivateVideo.vue | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index 3fdd33f..1251953 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -50,10 +50,15 @@ configuration: { iceServers: [ { - url: 'stun:stun.l.google.com:19302' + urls: 'stun:stun.l.google.com:19302' }, { - url: 'turn:www.boxim.online:3478', + urls: 'turn:www.boxim.online:3478', + credential: 'admin123', + username: 'admin' + }, + { + urls: 'stun:www.boxim.online:3478', credential: 'admin123', username: 'admin' } From 524ed9841936cee1261e73516a393a0c5f66779e Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 23:44:41 +0800 Subject: [PATCH 23/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/components/chat/ChatPrivateVideo.vue | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index 1251953..6053a08 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -58,9 +58,7 @@ username: 'admin' }, { - urls: 'stun:www.boxim.online:3478', - credential: 'admin123', - username: 'admin' + urls: 'stun:www.boxim.online:3478' } ] } @@ -91,6 +89,7 @@ this.timerx && clearInterval(this.timerx); this.timerx = setInterval(() => { console.log(this.peerConnection.iceConnectionState); + console.log(this.peerConnection.iceGatheringState); }, 3000) }); @@ -114,7 +113,7 @@ closeCamera() { if (this.stream) { - this.stream.getVideoTracks().forEach((track) => { + this.stream.getTracks().forEach((track) => { track.stop(); }); this.$refs.mineVideo.srcObject = null; From e713639bc214c4a33817bd9b0274df2b65dd884f Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Fri, 25 Nov 2022 23:53:55 +0800 Subject: [PATCH 24/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/chat/ChatPrivateVideo.vue | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index 6053a08..d704e04 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -48,8 +48,7 @@ state: 'NOT_CONNECTED', candidates: [], configuration: { - iceServers: [ - { + iceServers: [{ urls: 'stun:stun.l.google.com:19302' }, { @@ -127,15 +126,23 @@ console.log("onaddstream") this.$refs.friendVideo.srcObject = e.streams[0]; }; + this.peerConnection.onicegatheringstatechange = (event) => { + if (this.peerConnection.iceGatheringState == 'complete') { + this.candidates.forEach((candidate) => { + this.sendCandidate(candidate); + }) + } + } + this.peerConnection.onicecandidate = (event) => { if (event.candidate) { - if (this.state == 'CONNECTED') { - // 已连接,直接发送 - this.sendCandidate(event.candidate); - } else { - // 未连接,缓存起来,连接后再发送 - this.candidates.push(event.candidate) - } + // if (this.state == 'CONNECTED') { + // // 已连接,直接发送 + // this.sendCandidate(event.candidate); + // } else { + // 未连接,缓存起来,连接后再发送 + this.candidates.push(event.candidate) + //} } } if (stream) { @@ -158,9 +165,9 @@ // 状态为连接中 this.state = 'CONNECTED'; // 发送candidate - this.candidates.forEach((candidate) => { - this.sendCandidate(candidate); - }) + // this.candidates.forEach((candidate) => { + // this.sendCandidate(candidate); + // }) } if (msg.type == this.$enums.MESSAGE_TYPE.RTC_REJECT) { this.$message.error("对方拒绝了您的视频请求"); From ecc8e23e1dcd42c4f2101eb15c30b5bb43afc301 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Sat, 26 Nov 2022 00:06:50 +0800 Subject: [PATCH 25/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/chat/ChatPrivateVideo.vue | 35 ++++++++----------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index d704e04..a9a1810 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -48,16 +48,17 @@ state: 'NOT_CONNECTED', candidates: [], configuration: { - iceServers: [{ + iceServers: [ + { urls: 'stun:stun.l.google.com:19302' }, { - urls: 'turn:www.boxim.online:3478', + urls: 'turn:8.134.92.70:3478', credential: 'admin123', username: 'admin' }, { - urls: 'stun:www.boxim.online:3478' + urls: 'stun:8.134.92.70:3478' } ] } @@ -126,23 +127,15 @@ console.log("onaddstream") this.$refs.friendVideo.srcObject = e.streams[0]; }; - this.peerConnection.onicegatheringstatechange = (event) => { - if (this.peerConnection.iceGatheringState == 'complete') { - this.candidates.forEach((candidate) => { - this.sendCandidate(candidate); - }) - } - } - this.peerConnection.onicecandidate = (event) => { if (event.candidate) { - // if (this.state == 'CONNECTED') { - // // 已连接,直接发送 - // this.sendCandidate(event.candidate); - // } else { - // 未连接,缓存起来,连接后再发送 - this.candidates.push(event.candidate) - //} + if (this.state == 'CONNECTED') { + // 已连接,直接发送 + this.sendCandidate(event.candidate); + } else { + // 未连接,缓存起来,连接后再发送 + this.candidates.push(event.candidate) + } } } if (stream) { @@ -165,9 +158,9 @@ // 状态为连接中 this.state = 'CONNECTED'; // 发送candidate - // this.candidates.forEach((candidate) => { - // this.sendCandidate(candidate); - // }) + this.candidates.forEach((candidate) => { + this.sendCandidate(candidate); + }) } if (msg.type == this.$enums.MESSAGE_TYPE.RTC_REJECT) { this.$message.error("对方拒绝了您的视频请求"); From 43b6c5e27d0c52a96bde7ac99f24aac0a8bbf422 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Mon, 28 Nov 2022 23:15:17 +0800 Subject: [PATCH 26/28] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD-=E5=BC=80=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/chat/ChatPrivateVideo.vue | 86 +++++++++++++------ im-ui/src/components/chat/VideoAcceptor.vue | 2 +- im-ui/src/main.js | 1 + 3 files changed, 63 insertions(+), 26 deletions(-) diff --git a/im-ui/src/components/chat/ChatPrivateVideo.vue b/im-ui/src/components/chat/ChatPrivateVideo.vue index a9a1810..a119436 100644 --- a/im-ui/src/components/chat/ChatPrivateVideo.vue +++ b/im-ui/src/components/chat/ChatPrivateVideo.vue @@ -1,17 +1,20 @@ @@ -58,7 +58,7 @@ import UserInfo from '../components/common/UserInfo.vue'; import FullImage from '../components/common/FullImage.vue'; import ChatPrivateVideo from '../components/chat/ChatPrivateVideo.vue'; - import VideoAcceptor from '../components/chat/VideoAcceptor.vue'; + import ChatVideoAcceptor from '../components/chat/ChatVideoAcceptor.vue'; export default { @@ -68,7 +68,7 @@ UserInfo, FullImage, ChatPrivateVideo, - VideoAcceptor + ChatVideoAcceptor }, data() { return { @@ -156,6 +156,8 @@ this.$store.commit("openChat", chatInfo); // 插入消息 this.$store.commit("insertMessage", msg); + // 播放提示音 + this.playAudioTip(); }, handleGroupMessage(msg) { // 群聊缓存存在,直接插入群聊消息 @@ -184,6 +186,8 @@ this.$store.commit("openChat", chatInfo); // 插入消息 this.$store.commit("insertMessage", msg); + // 播放提示音 + this.playAudioTip(); }, handleExit() { this.$http({ @@ -194,6 +198,12 @@ location.href = "/"; }) }, + playAudioTip(){ + let audio = new Audio(); + let url = require(`@/assets/audio/tip.wav`); + audio.src = url; + audio.play(); + }, showSetting() { this.showSettingDialog = true; }, From c7a64075a7bad00c687e6936b73fa18d1989aef9 Mon Sep 17 00:00:00 2001 From: "xie.bx" Date: Tue, 29 Nov 2022 19:35:16 +0800 Subject: [PATCH 28/28] =?UTF-8?q?=E5=91=BD=E5=90=8D=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-ui/src/components/chat/ChatMessageItem.vue | 364 ++++++++++++++++++ .../src/components/chat/ChatVideoAcceptor.vue | 131 +++++++ 2 files changed, 495 insertions(+) create mode 100644 im-ui/src/components/chat/ChatMessageItem.vue create mode 100644 im-ui/src/components/chat/ChatVideoAcceptor.vue diff --git a/im-ui/src/components/chat/ChatMessageItem.vue b/im-ui/src/components/chat/ChatMessageItem.vue new file mode 100644 index 0000000..eb4cdc1 --- /dev/null +++ b/im-ui/src/components/chat/ChatMessageItem.vue @@ -0,0 +1,364 @@ + + + + + diff --git a/im-ui/src/components/chat/ChatVideoAcceptor.vue b/im-ui/src/components/chat/ChatVideoAcceptor.vue new file mode 100644 index 0000000..77c97e3 --- /dev/null +++ b/im-ui/src/components/chat/ChatVideoAcceptor.vue @@ -0,0 +1,131 @@ + + + + +