mirror of
https://github.com/tl-open-source/tl-rtc-file.git
synced 2025-09-26 19:41:16 +08:00
feat: socket heartbeat
feat: video face mode feat: change nickname feat: update self connect css feat: docker-compose inner env fix: some lang error
This commit is contained in:
184
docker-compose-with-all-env.yml
Normal file
184
docker-compose-with-all-env.yml
Normal file
@@ -0,0 +1,184 @@
|
||||
## !!!!!!用于docker-compose部署并启动官方镜像!!!!!!
|
||||
## !!!!!!内置配置的形式启动!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
version: '3'
|
||||
|
||||
################## 按需修改好配置
|
||||
x-tlrtcfile-env: &tlrtcfile-env
|
||||
## api服务端口
|
||||
tl_rtc_file_api_port: 9092
|
||||
## websocket服务端口
|
||||
tl_rtc_file_socket_port: 8444
|
||||
## websocket服务地址
|
||||
tl_rtc_file_socket_host: 127.0.0.1:8444
|
||||
## webrtc-stun中继服务地址
|
||||
tl_rtc_file_webrtc_stun_host: stun:127.0.0.1:3478
|
||||
## webrtc-turn中继服务地址
|
||||
tl_rtc_file_webrtc_turn_host: turn:127.0.0.1:3478?transport=udp
|
||||
## webrtc中继服务用户名
|
||||
tl_rtc_file_webrtc_turn_username: tlrtcfile
|
||||
## webrtc中继服务密码
|
||||
tl_rtc_file_webrtc_turn_credential: tlrtcfile
|
||||
## webrtc中继服务Secret
|
||||
tl_rtc_file_webrtc_turn_secret: tlrtcfile
|
||||
## webrtc中继服务帐号过期时间 (毫秒)
|
||||
tl_rtc_file_webrtc_turn_expire: 86400000
|
||||
## 是否开启数据库
|
||||
tl_rtc_file_db_open: true
|
||||
## 数据库地址
|
||||
tl_rtc_file_db_mysql_host: mysql
|
||||
## 数据库端口
|
||||
tl_rtc_file_db_mysql_port: 3306
|
||||
## 数据库名称
|
||||
tl_rtc_file_db_mysql_dbName: webchat
|
||||
## 数据库用户名
|
||||
tl_rtc_file_db_mysql_user: tlrtcfile
|
||||
## 数据库密码
|
||||
tl_rtc_file_db_mysql_password: tlrtcfile
|
||||
## oss-seafile存储库ID
|
||||
tl_rtc_file_oss_seafile_repoid:
|
||||
## oss-seafile地址
|
||||
tl_rtc_file_oss_seafile_host:
|
||||
## oss-seafile用户名
|
||||
tl_rtc_file_oss_seafile_username:
|
||||
## oss-seafile密码
|
||||
tl_rtc_file_oss_seafile_password:
|
||||
## oss-alyun存储accessKey
|
||||
tl_rtc_file_oss_alyun_AccessKey:
|
||||
## oss-aly存储SecretKey
|
||||
tl_rtc_file_oss_alyun_Secretkey:
|
||||
## oss-aly存储bucket
|
||||
tl_rtc_file_oss_alyun_bucket:
|
||||
## oss-txyun存储accessKey
|
||||
tl_rtc_file_oss_txyun_AccessKey:
|
||||
## oss-txyunt存储SecretKey
|
||||
tl_rtc_file_oss_txyun_Secretkey:
|
||||
## oss-txyun存储bucket
|
||||
tl_rtc_file_oss_txyun_bucket:
|
||||
## oss-qiniuyun存储accessKey
|
||||
tl_rtc_file_oss_qiniuyun_AccessKey:
|
||||
## oss-qiniuyunt存储SecretKey
|
||||
tl_rtc_file_oss_qiniuyun_Secretkey:
|
||||
## oss-qiniuyun存储bucket
|
||||
tl_rtc_file_oss_qiniuyun_bucket:
|
||||
## 管理后台房间号
|
||||
tl_rtc_file_manage_room: tlrtcfile
|
||||
## 管理后台密码
|
||||
tl_rtc_file_manage_password: tlrtcfile
|
||||
## openai-key,如果有多个key,逗号分隔
|
||||
tl_rtc_file_openai_keys:
|
||||
## 企业微信通知开关
|
||||
tl_rtc_file_notify_open: false
|
||||
## 企业微信通知机器人KEY,正常通知,如果有多个key,逗号分隔
|
||||
tl_rtc_file_notify_qiwei_normal:
|
||||
## 企业微信通知机器人KEY,错误通知,如果有多个key,逗号分隔
|
||||
tl_rtc_file_notify_qiwei_error:
|
||||
|
||||
|
||||
services:
|
||||
|
||||
#http模式启动api服务
|
||||
api-http:
|
||||
profiles: ['http']
|
||||
image: iamtsm/tl-rtc-file-api
|
||||
container_name: api
|
||||
environment:
|
||||
<<: *tlrtcfile-env
|
||||
tl_rtc_file_env_mode: http
|
||||
command:
|
||||
- tlapi
|
||||
ports:
|
||||
- 9092:9092
|
||||
links:
|
||||
- mysql
|
||||
depends_on:
|
||||
- mysql
|
||||
- coturn
|
||||
|
||||
#https模式启动api服务
|
||||
api-https:
|
||||
profiles: ['https']
|
||||
image: iamtsm/tl-rtc-file-api
|
||||
container_name: api
|
||||
environment:
|
||||
<<: *tlrtcfile-env
|
||||
tl_rtc_file_env_mode: https
|
||||
command:
|
||||
- tlapi
|
||||
ports:
|
||||
- 9092:9092
|
||||
links:
|
||||
- mysql
|
||||
depends_on:
|
||||
- mysql
|
||||
- coturn
|
||||
|
||||
#http模式启动socket服务
|
||||
socket-http:
|
||||
profiles: ['http']
|
||||
image: iamtsm/tl-rtc-file-socket
|
||||
container_name: socket
|
||||
command:
|
||||
- tlsocket
|
||||
environment:
|
||||
<<: *tlrtcfile-env
|
||||
tl_rtc_file_env_mode: http
|
||||
ports:
|
||||
- 8444:8444
|
||||
links:
|
||||
- mysql
|
||||
depends_on:
|
||||
- mysql
|
||||
- coturn
|
||||
|
||||
#https模式启动socket服务
|
||||
socket-https:
|
||||
profiles: ['https']
|
||||
image: iamtsm/tl-rtc-file-socket
|
||||
container_name: socket
|
||||
command:
|
||||
- tlsocket
|
||||
environment:
|
||||
<<: *tlrtcfile-env
|
||||
tl_rtc_file_env_mode: https
|
||||
ports:
|
||||
- 8444:8444
|
||||
links:
|
||||
- mysql
|
||||
depends_on:
|
||||
- mysql
|
||||
- coturn
|
||||
|
||||
#mysql服务
|
||||
mysql:
|
||||
profiles: ['http','https']
|
||||
image: iamtsm/tl-rtc-file-mysql
|
||||
container_name: mysql
|
||||
restart: always
|
||||
environment:
|
||||
#设置root密码
|
||||
MYSQL_ROOT_PASSWORD: tlrtcfile
|
||||
#设置数据库
|
||||
MYSQL_DATABASE: webchat
|
||||
#设置用户
|
||||
MYSQL_USER: tlrtcfile
|
||||
#设置用户密码
|
||||
MYSQL_PASSWORD: tlrtcfile
|
||||
ports:
|
||||
- 3306:3306
|
||||
volumes:
|
||||
- ./db:/var/lib/mysql
|
||||
- ./my.cnf:/etc/mysql/conf.d/my.cnf
|
||||
- ./log:/var/log/mysql
|
||||
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
|
||||
#coturn服务
|
||||
coturn:
|
||||
profiles: ['http','https']
|
||||
image: iamtsm/tl-rtc-file-coturn
|
||||
container_name: coturn
|
||||
ports:
|
||||
- "3478:3478/udp"
|
||||
- "3478:3478/tcp"
|
||||
volumes:
|
||||
- ./turnserver-with-secret-user.conf:/etc/turnserver.conf
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "10.4.5",
|
||||
"version": "10.4.6",
|
||||
"socket": {
|
||||
"port": "请到 tlrtcfile.env 中进行配置",
|
||||
"host": "请到 tlrtcfile.env 中进行配置"
|
||||
|
@@ -258,7 +258,6 @@ body {
|
||||
.tl-rtc-file-user {
|
||||
padding: 10px 20px 0px 10px;
|
||||
cursor: pointer;
|
||||
background-color: rgb(248, 253, 255);
|
||||
border-radius: 10px;
|
||||
box-shadow: rgba(0, 0, 0, 0.4) 0px 2px 3px;
|
||||
transition: box-shadow 0.3s;
|
||||
@@ -1081,7 +1080,6 @@ body {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
.chating_input_body{
|
||||
bottom: 0px;
|
||||
position: absolute;
|
||||
@@ -1111,7 +1109,6 @@ body {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
|
||||
.remote_user_info{
|
||||
text-align: left;
|
||||
padding: 20px 20px 0 20px;
|
||||
@@ -1142,7 +1139,7 @@ body {
|
||||
max-width: 40px;
|
||||
width: 5% !important;
|
||||
margin-left: 50% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.tl-rtc-file-tool-mobile {
|
||||
padding: 5px !important;
|
||||
@@ -1167,18 +1164,18 @@ body {
|
||||
margin: 10px 20px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.5s;
|
||||
transition: all 0.3s;
|
||||
font-weight: bold;
|
||||
color: #595252e3;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.tl-rtc-file-live-user-choose svg{
|
||||
font-size: 3rem;
|
||||
font-size: 2rem;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.tl-rtc-file-live-user-choose:hover{
|
||||
color: black;
|
||||
color: #79b0e8;
|
||||
}
|
||||
|
||||
/* 500px以下 */
|
||||
|
@@ -330,11 +330,13 @@
|
||||
<!-- 自己 -->
|
||||
<div class="layui-row" style="margin-top: 30px;" v-show="socketId !== 0">
|
||||
<div class="layui-col-xs12 tl-rtc-file-user-list">
|
||||
<div class="tl-rtc-file-user">
|
||||
<div class="tl-rtc-file-user-body">
|
||||
<svg class="icon" aria-hidden="true" style="width: 32px;height: 32px;">
|
||||
<use xlink:href="#icon-rtc-file-icon-test"></use>
|
||||
</svg>
|
||||
<div class="tl-rtc-file-user" style="background: #f6fdff;">
|
||||
<div class="tl-rtc-file-user-body" @click="changeNickName()">
|
||||
<div>
|
||||
<svg class="icon" aria-hidden="true" style="width: 32px;height: 32px;">
|
||||
<use xlink:href="#icon-rtc-file-jiangbei-"></use>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="tl-rtc-file-user-body-left">
|
||||
<b class="tl-rtc-file-user-body-left-nick">
|
||||
<b v-show="owner" style="color: #51d788;">【{{roomTypeName}}】-</b>
|
||||
@@ -1035,13 +1037,18 @@
|
||||
</svg>
|
||||
</div>
|
||||
<div class="tl-rtc-file-mask-media-video-tool">
|
||||
<div class="tl-rtc-file-mask-media-video-tool-item" @click="changeShareStream('video','video')">
|
||||
<div class="tl-rtc-file-mask-media-video-tool-item" @click="changeVideoShareMediaTrackAndStream()">
|
||||
<svg class="icon" aria-hidden="true" style="width: 18px;height: 18px;">
|
||||
<use xlink:href="#icon-rtc-file-xiangjifanzhuan"></use>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="tl-rtc-file-mask-media-video-tool-item" @click="changeShareStreamSwitch('video','video')">
|
||||
<svg class="icon" aria-hidden="true" style="width: 18px;height: 18px;">
|
||||
<use v-if="isCameraEnabled" xlink:href="#icon-rtc-file-shexiangtou"></use>
|
||||
<use v-else xlink:href="#icon-rtc-file-shexiangtou_guanbi"></use>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="tl-rtc-file-mask-media-video-tool-item" @click="changeShareStream('video','audio')">
|
||||
<div class="tl-rtc-file-mask-media-video-tool-item" @click="changeShareStreamSwitch('video','audio')">
|
||||
<svg class="icon" aria-hidden="true" style="width: 18px;height: 18px;">
|
||||
<use v-if="isAudioEnabled" xlink:href="#icon-rtc-file-maikefeng-XDY"></use>
|
||||
<use v-else xlink:href="#icon-rtc-file-guanbimaikefeng"></use>
|
||||
@@ -1083,7 +1090,7 @@
|
||||
</svg>
|
||||
</div>
|
||||
<div class="tl-rtc-file-mask-media-video-tool">
|
||||
<div class="tl-rtc-file-mask-media-video-tool-item" @click="changeShareStream('screen','video')">
|
||||
<div class="tl-rtc-file-mask-media-video-tool-item" @click="changeShareStreamSwitch('screen','video')">
|
||||
<svg class="icon" aria-hidden="true" style="width: 18px;height: 18px;">
|
||||
<use v-if="isCameraEnabled" xlink:href="#icon-rtc-file-pingmugongxiang"></use>
|
||||
<use v-else xlink:href="#icon-rtc-file-guanbipingmu"></use>
|
||||
@@ -1126,6 +1133,11 @@
|
||||
</svg>
|
||||
</div>
|
||||
<div class="tl-rtc-file-mask-media-video-tool" v-show="owner">
|
||||
<div v-show="liveShareMode === 'video'" class="tl-rtc-file-mask-media-video-tool-item" @click="changeLiveVideoShareMediaTrackAndStream()">
|
||||
<svg class="icon" aria-hidden="true" style="width: 18px;height: 18px;">
|
||||
<use xlink:href="#icon-rtc-file-xiangjifanzhuan"></use>
|
||||
</svg>
|
||||
</div>
|
||||
<div v-show="changeLiveShareMediaTrackAndStreamTime === 0" class="tl-rtc-file-mask-media-video-tool-item" @click="changeLiveShareMediaTrackAndStream()">
|
||||
<svg class="icon" aria-hidden="true" style="width: 18px;height: 18px;">
|
||||
<use xlink:href="#icon-rtc-file-fanzhuanjingtou"></use>
|
||||
@@ -1134,7 +1146,7 @@
|
||||
<div v-show="changeLiveShareMediaTrackAndStreamTime > 0" class="tl-rtc-file-mask-media-video-tool-item layui-disabled" style="padding: 2px 10px 2px 10px">
|
||||
{{changeLiveShareMediaTrackAndStreamTime}}
|
||||
</div>
|
||||
<div class="tl-rtc-file-mask-media-video-tool-item" @click="changeShareStream('live', 'video')">
|
||||
<div class="tl-rtc-file-mask-media-video-tool-item" @click="changeShareStreamSwitch('live', 'video')">
|
||||
<svg v-if="liveShareMode === 'video'" class="icon" aria-hidden="true" style="width: 18px;height: 18px;">
|
||||
<use v-if="isCameraEnabled" xlink:href="#icon-rtc-file-shexiangtou"></use>
|
||||
<use v-else xlink:href="#icon-rtc-file-shexiangtou_guanbi"></use>
|
||||
@@ -1144,7 +1156,7 @@
|
||||
<use v-else xlink:href="#icon-rtc-file-guanbipingmu"></use>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="tl-rtc-file-mask-media-video-tool-item" @click="changeShareStream('live','audio')">
|
||||
<div class="tl-rtc-file-mask-media-video-tool-item" @click="changeShareStreamSwitch('live','audio')">
|
||||
<svg class="icon" aria-hidden="true" style="width: 18px;height: 18px;">
|
||||
<use v-if="isAudioEnabled" xlink:href="#icon-rtc-file-maikefeng-XDY"></use>
|
||||
<use v-else xlink:href="#icon-rtc-file-guanbimaikefeng"></use>
|
||||
@@ -1189,7 +1201,7 @@
|
||||
</svg>
|
||||
</div>
|
||||
<div class="tl-rtc-file-mask-media-video-tool">
|
||||
<div class="tl-rtc-file-mask-media-video-tool-item" @click="changeShareStream('audio','audio')">
|
||||
<div class="tl-rtc-file-mask-media-video-tool-item" @click="changeShareStreamSwitch('audio','audio')">
|
||||
<svg class="icon" aria-hidden="true" style="width: 18px;height: 18px;">
|
||||
<use v-if="isAudioEnabled" xlink:href="#icon-rtc-file-maikefeng-XDY"></use>
|
||||
<use v-else xlink:href="#icon-rtc-file-guanbimaikefeng"></use>
|
||||
|
@@ -135,6 +135,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then((initData) => {
|
||||
aiAnsweringTxtIntervalId: 0, //实现等待动画
|
||||
aiAnsweringTxt: "思考中...", //ai思考中的文字
|
||||
logsFilter: "", //日志过滤参数
|
||||
|
||||
changeLiveShareMediaTrackAndStreamTimeLimit : 9, //切换直播媒体流的时间限制, 允许9s内切换一次
|
||||
changeLiveShareMediaTrackAndStreamTime : 0, //可以下一次切换直播媒体流的时间
|
||||
changeLiveShareMediaTrackAndStreamIntervalId : 0, //切换直播媒体流的时间间隔id
|
||||
@@ -245,15 +246,85 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then((initData) => {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeNickName : function(){
|
||||
let that = this;
|
||||
layer.prompt({
|
||||
formType: 0,
|
||||
title: that.lang.changeNickName,
|
||||
value: "",
|
||||
}, function (value, index, elem) {
|
||||
if(value.length > 10 || tlrtcfile.containSymbol(value)){
|
||||
layer.msg(that.lang.changeNickNameLimit)
|
||||
return
|
||||
}
|
||||
|
||||
that.socket.emit("changeNickName", {
|
||||
room: that.roomId,
|
||||
from : that.socketId,
|
||||
nickName : value,
|
||||
preNickName : that.nickName
|
||||
})
|
||||
|
||||
that.nickName = value;
|
||||
layer.close(index);
|
||||
that.addUserLogs(that.lang.changeNickName + "," + value);
|
||||
return false
|
||||
});
|
||||
},
|
||||
//切换音视频场景下的摄像头前后置
|
||||
//切换媒体流之前,先将已关闭的媒体流打开之后再进行切换
|
||||
changeVideoShareMediaTrackAndStream : async function(){
|
||||
await this.changeShareStreamSwitch('video', 'video', 'open')
|
||||
await this.changeShareStreamSwitch('video', 'audio', 'open')
|
||||
|
||||
//切换摄像头前后置
|
||||
this.facingMode = this.facingMode === 'user' ? 'environment' : 'user'
|
||||
|
||||
let that = this;
|
||||
window.Bus.$emit("changeVideoShareMediaTrackAndStream", {
|
||||
kind : 'video',
|
||||
constraints : this.videoConstraints,
|
||||
rtcConns : this.rtcConns,
|
||||
callback : (success) => {
|
||||
if(!success){ //没有成功,切换回来
|
||||
this.facingMode = this.facingMode === 'user' ? 'environment' : 'user'
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
//切换直播场景下的视频摄像头前后置媒体流
|
||||
//切换媒体流之前,先将已关闭的媒体流打开之后再进行切换
|
||||
changeLiveVideoShareMediaTrackAndStream : async function(){
|
||||
await this.changeShareStreamSwitch('live', 'video', 'open')
|
||||
await this.changeShareStreamSwitch('live', 'audio', 'open')
|
||||
|
||||
//切换摄像头前后置
|
||||
this.facingMode = this.facingMode === 'user' ? 'environment' : 'user'
|
||||
|
||||
let that = this;
|
||||
|
||||
window.Bus.$emit("changeLiveShareMediaTrackAndStream", {
|
||||
type : 'video',
|
||||
kind : 'video',
|
||||
constraints : this.videoConstraints,
|
||||
rtcConns : this.rtcConns,
|
||||
callback : (success) => {
|
||||
if(!success){ //没有成功,切换回来
|
||||
that.facingMode = that.facingMode === 'user' ? 'environment' : 'user'
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
//切换直播媒体流,比如切换视频流和屏幕共享流
|
||||
//切换媒体流之前,先将已关闭的媒体流打开之后再进行切换
|
||||
changeLiveShareMediaTrackAndStream : async function(){
|
||||
//切换媒体流之前,先将已关闭的媒体流打开之后再进行切换
|
||||
if(this.liveShareMode === 'live'){
|
||||
//屏幕共享流只需要打开video通道即可
|
||||
await this.changeShareStream('live', 'video', 'open')
|
||||
await this.changeShareStreamSwitch('live', 'video', 'open')
|
||||
}else if(this.liveShareMode === 'video'){
|
||||
//视频流需要打开video和audio通道
|
||||
await this.changeShareStream('live', 'video', 'open')
|
||||
await this.changeShareStream('live', 'audio', 'open')
|
||||
await this.changeShareStreamSwitch('live', 'video', 'open')
|
||||
await this.changeShareStreamSwitch('live', 'audio', 'open')
|
||||
}
|
||||
|
||||
let that = this;
|
||||
@@ -282,7 +353,8 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then((initData) => {
|
||||
}, 1000);
|
||||
}
|
||||
},
|
||||
changeShareStream : async function(type, kind, value){
|
||||
//改变媒体流开关状态
|
||||
changeShareStreamSwitch : async function(type, kind, value){
|
||||
let stream = null;
|
||||
|
||||
if(type === 'video'){
|
||||
@@ -333,6 +405,7 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then((initData) => {
|
||||
this.isAudioEnabled = !this.isAudioEnabled
|
||||
}
|
||||
}
|
||||
|
||||
this.socket.emit('message', {
|
||||
emitType: "openCamera",
|
||||
room: this.roomId,
|
||||
@@ -342,7 +415,6 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then((initData) => {
|
||||
isCameraEnabled : this.isCameraEnabled,
|
||||
isAudioEnabled : this.isAudioEnabled
|
||||
});
|
||||
|
||||
},
|
||||
updateRemoteRtcState : async function(){
|
||||
for(let id in this.remoteMap){
|
||||
@@ -1660,8 +1732,6 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then((initData) => {
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
// 创建/加入语音连麦房间
|
||||
@@ -1693,8 +1763,8 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then((initData) => {
|
||||
return
|
||||
}
|
||||
if (this.isJoined) {
|
||||
layer.msg(this.lang.please_exit_then_join_screen)
|
||||
this.addUserLogs(this.lang.please_exit_then_join_screen)
|
||||
layer.msg(this.lang.please_exit_then_join_audio)
|
||||
this.addUserLogs(this.lang.please_exit_then_join_audio)
|
||||
return
|
||||
}
|
||||
let that = this;
|
||||
@@ -3381,10 +3451,19 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then((initData) => {
|
||||
socketListener: function () {
|
||||
let that = this;
|
||||
|
||||
this.socket.on("heartbeat", data => {
|
||||
if(data.status === 'ok'){
|
||||
that.addSysLogs("心跳检查正常 : " + data.status);
|
||||
}else{
|
||||
that.addSysLogs("socket心跳检查失败," + JSON.stringify(data));
|
||||
}
|
||||
})
|
||||
|
||||
this.socket.on('connect_error', error => {
|
||||
console.error('connect_error', error);
|
||||
if(error){
|
||||
layer.msg("socket服务连接失败,请检查socket服务是否正常启动 " + error.message);
|
||||
that.addSysLogs("socket服务连接失败,请检查socket服务是否正常启动" + error.message);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3771,6 +3850,14 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then((initData) => {
|
||||
that.addSysLogs(that.lang.current_number + ":" + data.mc + that.lang.online_number)
|
||||
});
|
||||
|
||||
//更新昵称
|
||||
this.socket.on('changeNickName', function (data) {
|
||||
that.setRemoteInfo(data.from, {
|
||||
nickName : data.nickName
|
||||
})
|
||||
that.addSysLogs(data.from + + that.lang.changeNickNameTo + " : " + data.nickName)
|
||||
});
|
||||
|
||||
//提示
|
||||
this.socket.on('tips', function (data) {
|
||||
if (window.layer) {
|
||||
@@ -4339,6 +4426,10 @@ axios.get("/api/comm/initData?turn="+useTurn, {}).then((initData) => {
|
||||
}, 5000);
|
||||
this.addSysLogs(this.lang.webrtc_check_init_done);
|
||||
|
||||
setInterval(async () => {
|
||||
this.socket.emit("heartbeat", {})
|
||||
}, 10000);
|
||||
|
||||
this.addSysLogs(this.lang.message_box_init);
|
||||
this.startPopUpMsg()
|
||||
this.addSysLogs(this.lang.message_box_init_done);
|
||||
|
@@ -8,6 +8,9 @@
|
||||
|
||||
const local_lang = {
|
||||
"en": {
|
||||
"changeNickNameTo" : "Change nickname to",
|
||||
"changeNickNameLimit" : "The nickname can only be Chinese or English within 10 characters",
|
||||
"changeNickName" : "Change nickname",
|
||||
"iamLiveViewer" : "i am live viewer",
|
||||
"iamLiveOwner" : "i am Live Owner",
|
||||
"chooseRoleEnter" : "Choose role enter",
|
||||
@@ -201,6 +204,7 @@ const local_lang = {
|
||||
"please_enter_audio_sharing_room_num" : "Please enter the audio sharing room number",
|
||||
"please_enter_screen_sharing_room_num": "Please enter the screen sharing room number",
|
||||
"please_enter_video_call_room_num": "Please enter the audio and video call room number",
|
||||
"please_exit_then_join_audio": "Please exit the room first and then enter the audio room",
|
||||
"please_exit_then_join_live": "Please exit the room first and then enter the live room",
|
||||
"please_exit_then_join_password_room": "Please exit the room first and then enter the password room",
|
||||
"please_exit_then_join_screen": "Please exit the room first and then initiate screen sharing",
|
||||
@@ -344,6 +348,9 @@ const local_lang = {
|
||||
"webrtc_ice_state" : "webrtc state"
|
||||
},
|
||||
"zh": {
|
||||
"changeNickNameTo" : "更新了昵称为",
|
||||
"changeNickName" : "修改昵称",
|
||||
"changeNickNameLimit" : "昵称长度限制为10个以内中英文字符",
|
||||
"iamLiveViewer" : "我是观众",
|
||||
"iamLiveOwner" : "我是主播",
|
||||
"chooseRoleEnter" : "选择身份进入",
|
||||
@@ -547,6 +554,7 @@ const local_lang = {
|
||||
"please_enter_audio_sharing_room_num" : "请输入语音连麦房间号",
|
||||
"please_enter_screen_sharing_room_num": "请输入屏幕共享房间号",
|
||||
"please_enter_video_call_room_num": "请输入音视频通话房间号",
|
||||
"please_exit_then_join_audio": "请先退出房间,然后进入语音连麦房间",
|
||||
"please_exit_then_join_live": "请先退出房间,然后进入直播间",
|
||||
"please_exit_then_join_password_room": "请先退出房间,然后进入密码房间",
|
||||
"please_exit_then_join_screen": "请先退出房间,然后发起屏幕共享",
|
||||
|
@@ -179,7 +179,7 @@ var videoShare = new Vue({
|
||||
this.videoDeviceList = list.videoDeviceList;
|
||||
this.loudspeakerDeviceList = list.loudspeakerDeviceList;
|
||||
},
|
||||
changeVideoShareDevice: async function ({constraints, kind, rtcConnect}) {
|
||||
changeVideoShareMediaTrackAndStream: async function ({constraints, kind, rtcConns, callback}) {
|
||||
//重新获取流
|
||||
let newStream = null;
|
||||
try{
|
||||
@@ -263,7 +263,7 @@ var videoShare = new Vue({
|
||||
window.Bus.$on("startVideoShare", this.startVideoShare);
|
||||
window.Bus.$on("stopVideoShare", this.stopVideoShare);
|
||||
window.Bus.$on("getVideoShareTrackAndStream", this.getVideoShareTrackAndStream);
|
||||
window.Bus.$on("changeVideoShareDevice", this.changeVideoShareDevice);
|
||||
window.Bus.$on("changeVideoShareMediaTrackAndStream", this.changeVideoShareMediaTrackAndStream);
|
||||
window.Bus.$on("getVideoShareDeviceList", this.getVideoShareDeviceList);
|
||||
}
|
||||
})
|
@@ -58,6 +58,23 @@ function sendFileDoneNotify(data) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发送修改昵称通知
|
||||
* @param {*} data
|
||||
*/
|
||||
function sendChangeNickNameNotify(data) {
|
||||
let notifyMsg = `## <font color='info'>文件传输通知</font> - <font color="warning">${data.title}</font>` +
|
||||
` - <font color="comment">${data.room}</font>\n` +
|
||||
`库记录ID: ${data.recoderId}\n` +
|
||||
`旧的昵称: ${data.oldNickName}\n` +
|
||||
`新的昵称: ${data.nickName}\n` +
|
||||
`当前时间: ${utils.formateDateTime(new Date(), "yyyy-MM-dd hh:mm:ss")}\n` +
|
||||
`访问IP: ${data.ip}\n` +
|
||||
`访问设备: ${data.userAgent}\n`;
|
||||
notify.requestMsg(notifyMsg)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发送文本内容通知
|
||||
* @param {*} data
|
||||
@@ -507,5 +524,6 @@ module.exports = {
|
||||
prepareCodeFileNotify,
|
||||
sendSystemErrorMsg,
|
||||
sendStartRemoteDrawNotify,
|
||||
sendStopRemoteDrawNotify
|
||||
sendStopRemoteDrawNotify,
|
||||
sendChangeNickNameNotify
|
||||
}
|
@@ -15,6 +15,8 @@ const rtcChatingRoom = require("./rtcChatingRoom/chatingRoom");
|
||||
const rtcOpenai = require("./rtcOpenai/openai");
|
||||
const rtcDraw = require("./rtcDraw/draw");
|
||||
const rtcPrepareCodeFile = require("./rtcCodeFile/prepareCodeFile");
|
||||
const rtcChangeNickName = require("./rtcChangeNickName/changeNickName")
|
||||
const rtcHeartbeat = require("./rtcHeartbeat/heartbeat");
|
||||
const rtcAddCodeFile = require("./rtcCodeFile/addCodeFile");
|
||||
const rtcGetCodeFile = require("./rtcCodeFile/getCodeFile");
|
||||
const rtcServerEvent = require("./rtcConstant").rtcServerEvent
|
||||
@@ -118,4 +120,14 @@ module.exports = (io, socket, tables, dbClient) => {
|
||||
socket.on(rtcServerEvent.getCodeFile, (data) => {
|
||||
rtcGetCodeFile.getCodeFile(io, socket, tables, dbClient, data)
|
||||
});
|
||||
|
||||
// 心跳
|
||||
socket.on(rtcServerEvent.heartbeat, (data) => {
|
||||
rtcHeartbeat.heartbeat(io, socket, tables, dbClient, data)
|
||||
});
|
||||
|
||||
// 修改昵称
|
||||
socket.on(rtcServerEvent.changeNickName, (data) => {
|
||||
rtcChangeNickName.changeNickName(io, socket, tables, dbClient, data)
|
||||
});
|
||||
}
|
105
svr/src/socket/rtcChangeNickName/changeNickName.js
Normal file
105
svr/src/socket/rtcChangeNickName/changeNickName.js
Normal file
@@ -0,0 +1,105 @@
|
||||
const daoDog = require("./../../dao/dog/dog")
|
||||
const bussinessNotify = require("./../../bussiness/notify/notifyHandler")
|
||||
const utils = require("./../../utils/utils");
|
||||
const rtcConstant = require("../rtcConstant");
|
||||
const rtcClientEvent = rtcConstant.rtcClientEvent
|
||||
const check = require("../../bussiness/check/content");
|
||||
|
||||
/**
|
||||
* 房间内更新昵称
|
||||
* 指定了to : 就会发送给指定的用户
|
||||
* 没有指定to : 广播给除了自己外的房间内的所有用户
|
||||
* @param {*} io socketio对象
|
||||
* @param {*} socket 单个socket连接
|
||||
* @param {*} tables 数据表对象
|
||||
* @param {*} dbClient sequelize-orm对象
|
||||
* @param {*} data event参数
|
||||
* @returns
|
||||
*/
|
||||
async function changeNickName(io, socket, tables, dbClient, data){
|
||||
try {
|
||||
let {handshake, userAgent, ip} = utils.getSocketClientInfo(socket);
|
||||
|
||||
let { nickName = '', preNickName = ''} = data;
|
||||
|
||||
if(nickName && nickName.length > 10){
|
||||
nickName = nickName.toString().substr(0, 9);
|
||||
}
|
||||
|
||||
await daoDog.addDogData({
|
||||
name: "修改个人昵称",
|
||||
roomId: data.room || "",
|
||||
socketId: "",
|
||||
device: userAgent,
|
||||
flag: 0,
|
||||
content: JSON.stringify(data),
|
||||
handshake: JSON.stringify(handshake),
|
||||
ip: ip
|
||||
}, tables, dbClient);
|
||||
|
||||
data.nickName = check.contentFilter(nickName);
|
||||
|
||||
bussinessNotify.sendChangeNickNameNotify({
|
||||
title: "修改个人昵称",
|
||||
room: data.room,
|
||||
nickName: data.nickName,
|
||||
preNickName: preNickName,
|
||||
userAgent: userAgent,
|
||||
ip: ip
|
||||
})
|
||||
|
||||
//更新下服务端存下的昵称
|
||||
io.sockets.connected[socket.id].nickName = nickName;
|
||||
|
||||
// 指定发送
|
||||
if(data.to && data.to !== ''){
|
||||
let toOtherSocket = io.sockets.connected[data.to];
|
||||
if(toOtherSocket){
|
||||
toOtherSocket.emit(rtcClientEvent.chatingRoom, data);
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 没指定,走广播(除了自己)
|
||||
let clientsInRoom = io.sockets.adapter.rooms[data.room];
|
||||
if (!clientsInRoom) {
|
||||
return
|
||||
}
|
||||
let otherSocketIds = Object.keys(clientsInRoom.sockets);
|
||||
for (let i = 0; i < otherSocketIds.length; i++) {
|
||||
if(data.from === otherSocketIds[i]){ //跳过自己
|
||||
continue;
|
||||
}
|
||||
let otherSocket = io.sockets.connected[otherSocketIds[i]];
|
||||
if(!otherSocket){
|
||||
continue;
|
||||
}
|
||||
otherSocket.emit(rtcClientEvent.changeNickName, data);
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
utils.tlConsole(e)
|
||||
socket.emit("tips", {
|
||||
room: data.room,
|
||||
to: socket.id,
|
||||
msg: "系统错误"
|
||||
});
|
||||
bussinessNotify.sendSystemErrorMsg({
|
||||
title: "socket-changeNickName",
|
||||
data: JSON.stringify(data),
|
||||
room: data.room,
|
||||
from : socket.id,
|
||||
msg : JSON.stringify({
|
||||
message: e.message,
|
||||
fileName: e.fileName,
|
||||
lineNumber: e.lineNumber,
|
||||
stack: e.stack,
|
||||
name: e.name
|
||||
}, null, '\t')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
changeNickName
|
||||
}
|
@@ -44,6 +44,10 @@ const rtcServerEvent = {
|
||||
addCodeFile : "addCodeFile",
|
||||
//获取取件码文件
|
||||
getCodeFile : "getCodeFile",
|
||||
//心跳
|
||||
heartbeat : "heartbeat",
|
||||
//修改昵称
|
||||
changeNickName : "changeNickName",
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,6 +128,10 @@ let rtcClientEvent = {
|
||||
addCodeFile : "addCodeFile",
|
||||
//获取取件码文件
|
||||
getCodeFile : "getCodeFile",
|
||||
//心跳
|
||||
heartbeat : "heartbeat",
|
||||
//修改昵称
|
||||
changeNickName : "changeNickName",
|
||||
}
|
||||
|
||||
/**
|
||||
|
26
svr/src/socket/rtcHeartbeat/heartbeat.js
Normal file
26
svr/src/socket/rtcHeartbeat/heartbeat.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const rtcConstant = require("../rtcConstant");
|
||||
const rtcClientEvent = rtcConstant.rtcClientEvent
|
||||
const utils = require("../../../src/utils/utils");
|
||||
|
||||
/**
|
||||
* 心跳
|
||||
* @param {*} io socketio对象
|
||||
* @param {*} socket 单个socket连接
|
||||
* @param {*} tables 数据表对象
|
||||
* @param {*} dbClient sequelize-orm对象
|
||||
* @param {*} data event参数
|
||||
* @returns
|
||||
*/
|
||||
async function heartbeat(io, socket, tables, dbClient, data){
|
||||
try{
|
||||
socket.emit(rtcClientEvent.heartbeat, {
|
||||
status : "ok"
|
||||
})
|
||||
}catch(e){
|
||||
utils.tlConsole(e)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
heartbeat
|
||||
}
|
@@ -54,6 +54,24 @@
|
||||
<div class="content unicode" style="display: block;">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">相机反转</div>
|
||||
<div class="code-name">&#xe6de;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">奖杯7-3</div>
|
||||
<div class="code-name">&#xe6bc;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">奖杯</div>
|
||||
<div class="code-name">&#xe6ea;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">老师</div>
|
||||
@@ -708,9 +726,9 @@
|
||||
<pre><code class="language-css"
|
||||
>@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('iconfont.woff2?t=1692323109723') format('woff2'),
|
||||
url('iconfont.woff?t=1692323109723') format('woff'),
|
||||
url('iconfont.ttf?t=1692323109723') format('truetype');
|
||||
src: url('iconfont.woff2?t=1692448975663') format('woff2'),
|
||||
url('iconfont.woff?t=1692448975663') format('woff'),
|
||||
url('iconfont.ttf?t=1692448975663') format('truetype');
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||
@@ -736,6 +754,33 @@
|
||||
<div class="content font-class">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-rtc-file-xiangjifanzhuan"></span>
|
||||
<div class="name">
|
||||
相机反转
|
||||
</div>
|
||||
<div class="code-name">.icon-rtc-file-xiangjifanzhuan
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-rtc-file-jiangbei-"></span>
|
||||
<div class="name">
|
||||
奖杯7-3
|
||||
</div>
|
||||
<div class="code-name">.icon-rtc-file-jiangbei-
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-rtc-file-jiangbei"></span>
|
||||
<div class="name">
|
||||
奖杯
|
||||
</div>
|
||||
<div class="code-name">.icon-rtc-file-jiangbei
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-rtc-file-laoshi"></span>
|
||||
<div class="name">
|
||||
@@ -1717,6 +1762,30 @@
|
||||
<div class="content symbol">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-rtc-file-xiangjifanzhuan"></use>
|
||||
</svg>
|
||||
<div class="name">相机反转</div>
|
||||
<div class="code-name">#icon-rtc-file-xiangjifanzhuan</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-rtc-file-jiangbei-"></use>
|
||||
</svg>
|
||||
<div class="name">奖杯7-3</div>
|
||||
<div class="code-name">#icon-rtc-file-jiangbei-</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-rtc-file-jiangbei"></use>
|
||||
</svg>
|
||||
<div class="name">奖杯</div>
|
||||
<div class="code-name">#icon-rtc-file-jiangbei</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-rtc-file-laoshi"></use>
|
||||
|
@@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4147343 */
|
||||
src: url('iconfont.woff2?t=1692323109723') format('woff2'),
|
||||
url('iconfont.woff?t=1692323109723') format('woff'),
|
||||
url('iconfont.ttf?t=1692323109723') format('truetype');
|
||||
src: url('iconfont.woff2?t=1692448975663') format('woff2'),
|
||||
url('iconfont.woff?t=1692448975663') format('woff'),
|
||||
url('iconfont.ttf?t=1692448975663') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@@ -13,6 +13,18 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-rtc-file-xiangjifanzhuan:before {
|
||||
content: "\e6de";
|
||||
}
|
||||
|
||||
.icon-rtc-file-jiangbei-:before {
|
||||
content: "\e6bc";
|
||||
}
|
||||
|
||||
.icon-rtc-file-jiangbei:before {
|
||||
content: "\e6ea";
|
||||
}
|
||||
|
||||
.icon-rtc-file-laoshi:before {
|
||||
content: "\e81f";
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@@ -5,6 +5,27 @@
|
||||
"css_prefix_text": "icon-rtc-file-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "3405264",
|
||||
"name": "相机反转",
|
||||
"font_class": "xiangjifanzhuan",
|
||||
"unicode": "e6de",
|
||||
"unicode_decimal": 59102
|
||||
},
|
||||
{
|
||||
"icon_id": "6162508",
|
||||
"name": "奖杯7-3",
|
||||
"font_class": "jiangbei-",
|
||||
"unicode": "e6bc",
|
||||
"unicode_decimal": 59068
|
||||
},
|
||||
{
|
||||
"icon_id": "12592991",
|
||||
"name": "奖杯",
|
||||
"font_class": "jiangbei",
|
||||
"unicode": "e6ea",
|
||||
"unicode_decimal": 59114
|
||||
},
|
||||
{
|
||||
"icon_id": "22960451",
|
||||
"name": "老师",
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user