Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
ws-rst
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
qlintonger xeno
ws-rst
Commits
e93a18f7
Commit
e93a18f7
authored
Feb 25, 2025
by
qlintonger xeno
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改挂断呼叫逻辑,增添命令行参数以及环境变量适配
parent
c633ebeb
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
458 additions
and
93 deletions
+458
-93
src/handles/handle_agora_call.rs
+420
-91
src/main.rs
+10
-2
src/utils/utils.rs
+28
-0
No files found.
src/handles/handle_agora_call.rs
View file @
e93a18f7
...
...
@@ -12,7 +12,8 @@ use tokio::time::sleep;
lazy_static!
{
pub
static
ref
refuse_procedure_map
:
DashMap
<
String
,
UnboundedSender
<
()
>>
=
DashMap
::
new
();
pub
static
ref
channel_hangup_procedure_map
:
DashMap
<
String
,
UnboundedSender
<
()
>>
=
DashMap
::
new
();
pub
static
ref
channel_hangup_procedure_map
:
DashMap
<
String
,
UnboundedSender
<
()
>>
=
DashMap
::
new
();
}
// 用户状态字段的索引
...
...
@@ -36,7 +37,15 @@ fn update_user_status(user_id: &str, status: &str, channel_id: &str, is_host: bo
let
mut
user_data
=
ONLINE_USERS
.get
(
user_id
)
.map
(|
v
|
v
.split
(
','
)
.map
(
String
::
from
)
.collect
())
.unwrap_or
(
vec!
[
"idle"
.into
(),
""
.into
(),
""
.into
(),
""
.into
(),
""
.into
(),
""
.into
(),
"0"
.into
()]);
.unwrap_or
(
vec!
[
"idle"
.into
(),
""
.into
(),
""
.into
(),
""
.into
(),
""
.into
(),
""
.into
(),
"0"
.into
(),
]);
user_data
[
STATUS_IDX
]
=
status
.into
();
user_data
[
CHANNEL_IDX
]
=
channel_id
.into
();
user_data
[
HOST_IDX
]
=
if
is_host
{
"1"
.into
()
}
else
{
"0"
.into
()
};
...
...
@@ -53,7 +62,11 @@ async fn send_inside_message(
from_id
:
&
String
,
)
{
println!
(
"发送给用户id {} 的消息 {}"
,
from_id
,
json_message
);
if
let
Err
(
e
)
=
event_sender
.send
(
Event
::
SendClientMessage
(
target_sender
.clone
(),
json_message
,
false
))
{
if
let
Err
(
e
)
=
event_sender
.send
(
Event
::
SendClientMessage
(
target_sender
.clone
(),
json_message
,
false
,
))
{
println!
(
"发送给用户id {} 独立消息失败:{:?}"
,
from_id
,
e
);
}
else
{
println!
(
"发送给用户id {} 独立消息成功"
,
from_id
);
...
...
@@ -73,8 +86,10 @@ async fn send_error_message(
"fromID"
:
"0"
,
"fromName"
:
"Server"
,
"toID"
:
from_id
})
.to_string
();
if
let
Err
(
e
)
=
event_sender
.send
(
Event
::
SendClientMessage
(
target_sender
.clone
(),
json
,
false
))
{
})
.to_string
();
if
let
Err
(
e
)
=
event_sender
.send
(
Event
::
SendClientMessage
(
target_sender
.clone
(),
json
,
false
))
{
println!
(
"发送给用户id {} 独立消息失败:{:?}"
,
from_id
,
e
);
}
else
{
println!
(
"发送给用户id {} 独立消息成功"
,
from_id
);
...
...
@@ -101,40 +116,65 @@ pub async fn handle_agora_call(
match
client_message_data
.msg_type
.as_str
()
{
"CancelCall"
=>
{
let
calling_to_id
=
&
client_message_data
.to_id
;
println!
(
"收到客户端取消呼叫 取消呼叫组: {} 呼叫方id {}"
,
calling_to_id
,
from_id
);
send_inside_message
(
&
target_sender_which
,
event_sender
,
serde_json
::
json!
({
println!
(
"收到客户端取消呼叫 取消呼叫组: {} 呼叫方id {}"
,
calling_to_id
,
from_id
);
send_inside_message
(
&
target_sender_which
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
"CmdCancelCall"
,
"fromID"
:
"0"
,
"fromName"
:
"Server"
,
"toID"
:
from_id
,
"msgData"
:
{
"channelId"
:
""
,
"rtcToken"
:
""
}
})
.to_string
(),
from_id
)
.await
;
})
.to_string
(),
from_id
,
)
.await
;
if
let
Some
(
user_status
)
=
ONLINE_USERS
.get
(
from_id
)
.map
(|
v
|
v
.clone
())
{
let
user_data
=
user_status
.split
(
','
)
.map
(
String
::
from
)
.collect
::
<
Vec
<
_
>>
();
if
user_data
[
CHANNEL_IDX
]
.is_empty
()
{
let
joined
=
update_user_status
(
from_id
,
"idle"
,
""
,
false
);
update_redis_async
(
from_id
.clone
(),
joined
);
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
return
;
}
let
to_hangup_ids
:
Vec
<
String
>
=
calling_to_id
.split
(
','
)
.map
(
String
::
from
)
.collect
();
let
to_hangup_ids
:
Vec
<
String
>
=
calling_to_id
.split
(
','
)
.map
(
String
::
from
)
.collect
();
for
to_id
in
to_hangup_ids
{
if
let
Some
(
sender
)
=
refuse_procedure_map
.get
(
&
to_id
)
{
sender
.send
(())
.ok
();
}
if
let
Some
(
other_data
)
=
ONLINE_USERS
.get
(
&
to_id
)
.map
(|
v
|
v
.clone
())
{
let
other_data_vec
=
other_data
.split
(
','
)
.map
(
String
::
from
)
.collect
::
<
Vec
<
_
>>
();
let
other_data_vec
=
other_data
.split
(
','
)
.map
(
String
::
from
)
.collect
::
<
Vec
<
_
>>
();
if
other_data_vec
[
CHANNEL_IDX
]
==
user_data
[
CHANNEL_IDX
]
{
if
let
Some
(
target_sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
entry
|
entry
.key
()
.
0
==
*
calling_to_id
)
.map
(|
entry
|
entry
.key
()
.clone
())
{
send_inside_message
(
&
target_sender
,
event_sender
,
serde_json
::
json!
({
if
let
Some
(
target_sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
entry
|
entry
.key
()
.
0
==
*
calling_to_id
)
.map
(|
entry
|
entry
.key
()
.clone
())
{
send_inside_message
(
&
target_sender
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
"CmdHangup"
,
"fromID"
:
"0"
,
"fromName"
:
"Server"
,
"toID"
:
to_id
,
"msgData"
:
{
"channelId"
:
""
,
"rtcToken"
:
""
}
})
.to_string
(),
&
to_id
)
.await
;
})
.to_string
(),
&
to_id
,
)
.await
;
let
joined
=
update_user_status
(
&
to_id
,
"idle"
,
""
,
false
);
update_redis_async
(
to_id
,
joined
);
}
else
{
...
...
@@ -145,19 +185,36 @@ pub async fn handle_agora_call(
}
let
joined
=
update_user_status
(
from_id
,
"idle"
,
""
,
false
);
update_redis_async
(
from_id
.clone
(),
joined
);
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
}
}
"Call"
=>
{
let
calling_to_id
=
&
client_message_data
.to_id
;
println!
(
"收到客户端呼叫 呼叫方id {} 呼叫组id {}"
,
from_id
,
calling_to_id
);
println!
(
"收到客户端呼叫 呼叫方id {} 呼叫组id {}"
,
from_id
,
calling_to_id
);
if
calling_to_id
.is_empty
()
{
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"请指定呼叫对象"
)
.await
;
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"请指定呼叫对象"
,
)
.await
;
return
;
}
if
calling_to_id
==
from_id
{
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"不能给自己打电话"
)
.await
;
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"不能给自己打电话"
,
)
.await
;
return
;
}
...
...
@@ -168,28 +225,55 @@ pub async fn handle_agora_call(
}
else
{
user_data
[
CHANNEL_IDX
]
.clone
()
};
println!
(
"当前用户channelId {} 呼叫方id集合是 {:?}"
,
channel_id
,
calling_to_id
.split
(
','
)
.collect
::
<
Vec
<
_
>>
());
println!
(
"当前用户channelId {} 呼叫方id集合是 {:?}"
,
channel_id
,
calling_to_id
.split
(
','
)
.collect
::
<
Vec
<
_
>>
()
);
let
mut
refuse_users
=
Vec
::
new
();
for
to_id
in
calling_to_id
.split
(
','
)
{
if
!
ONLINE_USERS
.contains_key
(
to_id
)
{
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"对方不在线"
)
.await
;
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"对方不在线"
,
)
.await
;
continue
;
}
if
let
Some
(
to_status
)
=
ONLINE_USERS
.get
(
to_id
)
.map
(|
v
|
v
.clone
())
{
let
to_data
=
to_status
.split
(
','
)
.map
(
String
::
from
)
.collect
::
<
Vec
<
_
>>
();
if
to_data
[
STATUS_IDX
]
!=
"idle"
{
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"对方正在呼叫中"
)
.await
;
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"对方正在呼叫中"
,
)
.await
;
continue
;
}
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
to_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
to_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
"Call"
,
"fromID"
:
from_id
,
"fromName"
:
client_message_data
.from_name
,
"toID"
:
to_id
,
"msgData"
:
{
"channelId"
:
channel_id
,
"rtcToken"
:
""
}
})
.to_string
(),
&
to_id
.to_string
())
.await
;
})
.to_string
(),
&
to_id
.to_string
(),
)
.await
;
let
joined
=
update_user_status
(
to_id
,
"callin"
,
&
channel_id
,
false
);
update_redis_async
(
to_id
.to_string
(),
joined
);
refuse_users
.push
(
to_id
.to_string
());
...
...
@@ -200,17 +284,30 @@ pub async fn handle_agora_call(
}
if
!
refuse_users
.is_empty
()
{
let
status
=
if
user_data
[
STATUS_IDX
]
==
"calling"
{
"calling"
}
else
{
"callout"
};
send_inside_message
(
&
target_sender_which
,
event_sender
,
serde_json
::
json!
({
let
status
=
if
user_data
[
STATUS_IDX
]
==
"calling"
{
"calling"
}
else
{
"callout"
};
send_inside_message
(
&
target_sender_which
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
"CmdCall"
,
"fromID"
:
calling_to_id
,
"fromName"
:
client_message_data
.from_name
,
"toID"
:
from_id
,
"msgData"
:
{
"channelId"
:
channel_id
,
"rtcToken"
:
""
}
})
.to_string
(),
from_id
)
.await
;
})
.to_string
(),
from_id
,
)
.await
;
let
joined
=
update_user_status
(
from_id
,
status
,
&
channel_id
,
false
);
update_redis_async
(
from_id
.clone
(),
joined
);
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
for
user_id
in
refuse_users
{
let
(
cancel_tx
,
mut
cancel_rx
)
=
mpsc
::
unbounded_channel
::
<
()
>
();
...
...
@@ -278,41 +375,72 @@ pub async fn handle_agora_call(
let
channel_id
=
user_data_vec
[
CHANNEL_IDX
]
.clone
();
let
joined
=
update_user_status
(
from_id
,
"idle"
,
""
,
false
);
update_redis_async
(
from_id
.clone
(),
joined
);
send_inside_message
(
&
target_sender_which
,
event_sender
,
serde_json
::
json!
({
send_inside_message
(
&
target_sender_which
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
"CmdHangup"
,
"fromID"
:
"0"
,
"fromName"
:
"Server"
,
"toID"
:
from_id
,
"msgData"
:
{
"channelId"
:
""
,
"rtcToken"
:
""
}
})
.to_string
(),
from_id
)
.await
;
})
.to_string
(),
from_id
,
)
.await
;
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
client_message_data
.to_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
client_message_data
.to_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
"CmdRefuse"
,
"fromID"
:
from_id
,
"fromName"
:
"Server"
,
"toID"
:
client_message_data
.to_id
,
"msgData"
:
{
"channelId"
:
""
,
"rtcToken"
:
""
}
})
.to_string
(),
&
client_message_data
.to_id
)
.await
;
})
.to_string
(),
&
client_message_data
.to_id
,
)
.await
;
}
else
{
println!
(
"找不到toID对应的sender"
);
}
let
chatters
=
get_users_by_channel
(
&
channel_id
);
if
chatters
.len
()
==
1
{
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
chatters
[
0
])
.map
(|
e
|
e
.key
()
.clone
())
{
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
chatters
[
0
])
.map
(|
e
|
e
.key
()
.clone
())
{
let
joined
=
update_user_status
(
&
chatters
[
0
],
"idle"
,
""
,
false
);
update_redis_async
(
chatters
[
0
]
.clone
(),
joined
);
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
"CmdCancelCall"
,
"fromID"
:
"0"
,
"fromName"
:
"Server"
,
"toID"
:
chatters
[
0
],
"msgData"
:
{
"channelId"
:
""
,
"rtcToken"
:
""
}
})
.to_string
(),
&
chatters
[
0
])
.await
;
})
.to_string
(),
&
chatters
[
0
],
)
.await
;
}
}
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
}
}
...
...
@@ -321,7 +449,13 @@ pub async fn handle_agora_call(
if
let
Some
(
user_data
)
=
ONLINE_USERS
.get
(
from_id
)
.map
(|
v
|
v
.clone
())
{
let
user_data_vec
=
user_data
.split
(
','
)
.map
(
String
::
from
)
.collect
::
<
Vec
<
_
>>
();
if
user_data_vec
[
HOST_IDX
]
!=
"1"
{
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"只有主持人可以结束会议!"
)
.await
;
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"只有主持人可以结束会议!"
,
)
.await
;
}
else
{
let
channel_id
=
user_data_vec
[
CHANNEL_IDX
]
.clone
();
if
!
channel_id
.is_empty
()
{
...
...
@@ -329,17 +463,30 @@ pub async fn handle_agora_call(
for
user_id
in
&
users
{
let
joined
=
update_user_status
(
user_id
,
"idle"
,
""
,
false
);
update_redis_async
(
user_id
.clone
(),
joined
);
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
*
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
*
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
"CmdEndMeeting"
,
"fromID"
:
"0"
,
"fromName"
:
"Server"
,
"toID"
:
user_id
,
"msgData"
:
{
"channelId"
:
""
,
"rtcToken"
:
""
}
})
.to_string
(),
user_id
)
.await
;
})
.to_string
(),
user_id
,
)
.await
;
}
}
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
}
}
}
...
...
@@ -352,41 +499,87 @@ pub async fn handle_agora_call(
let
channel_id
=
user_data_vec
[
CHANNEL_IDX
]
.clone
();
let
joined
=
update_user_status
(
from_id
,
"idle"
,
""
,
false
);
update_redis_async
(
from_id
.clone
(),
joined
);
send_inside_message
(
&
target_sender_which
,
event_sender
,
serde_json
::
json!
({
send_inside_message
(
&
target_sender_which
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
"CmdHangup"
,
"fromID"
:
"0"
,
"fromName"
:
"Server"
,
"toID"
:
from_id
,
"msgData"
:
{
"channelId"
:
""
,
"rtcToken"
:
""
}
})
.to_string
(),
from_id
)
.await
;
})
.to_string
(),
from_id
,
)
.await
;
let
remaining_users
=
get_users_by_channel
(
&
channel_id
);
if
remaining_users
.is_empty
()
{
println!
(
"当前频道没有人员,请重新发起通话"
);
}
else
{
for
user_id
in
&
remaining_users
{
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
*
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
*
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
"CmdLeave"
,
"fromID"
:
from_id
,
"fromName"
:
"Unknown"
,
"toID"
:
user_id
,
"msgData"
:
{}
})
.to_string
(),
user_id
)
.await
;
})
.to_string
(),
user_id
,
)
.await
;
}
}
if
remaining_users
.len
()
==
1
{
let
user_id
=
remaining_users
[
0
]
.clone
();
let
(
cancel_tx
,
mut
cancel_rx
)
=
mpsc
::
unbounded_channel
::
<
()
>
();
channel_hangup_procedure_map
.insert
(
channel_id
.clone
(),
cancel_tx
);
let
event_sender_clone
=
event_sender
.clone
();
let
channel_id_clone
=
channel_id
.clone
();
tokio
::
spawn
(
async
move
{
let
start_time
=
tokio
::
time
::
Instant
::
now
();
let
mut
interval
=
tokio
::
time
::
interval
(
Duration
::
from_secs
(
1
));
let
mut
should_cancel
=
false
;
tokio
::
select!
{
_
=
sleep
(
Duration
::
from_secs
(
15
))
=>
{
println!
(
"20s内如果该频道与会人数仍为1,则对剩下来的用户发送CmdHangup指令 {}"
,
user_id
);
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
let
joined
=
update_user_status
(
&
user_id
,
"idle"
,
""
,
false
);
_
=
async
{
loop
{
interval
.tick
()
.await
;
// 检查频道中是否存在 callin 状态的用户
let
has_callin
=
ONLINE_USERS
.iter
()
.filter
(|
e
|
e
.value
()
.split
(
','
)
.nth
(
CHANNEL_IDX
)
.unwrap_or
(
""
)
==
channel_id_clone
)
.any
(|
e
|
e
.value
()
.split
(
','
)
.nth
(
STATUS_IDX
)
.unwrap_or
(
""
)
==
"callin"
);
if
has_callin
{
println!
(
"检测到频道 {} 有用户处于呼叫状态,取消挂断任务"
,
channel_id_clone
);
should_cancel
=
true
;
break
;
}
if
start_time
.elapsed
()
.as_secs
()
>=
15
{
break
;
}
}
if
!
should_cancel
{
// 最终检查:只需要确认当前频道人数是否为1
let
current_users
=
get_users_by_channel
(
&
channel_id_clone
);
if
current_users
.len
()
==
1
{
if
let
Some
(
user_id
)
=
current_users
.first
()
{
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
*
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
let
joined
=
update_user_status
(
user_id
,
"idle"
,
""
,
false
);
update_redis_async
(
user_id
.clone
(),
joined
);
send_inside_message
(
&
sender
,
&
event_sender_clone
,
serde_json
::
json!
({
"msgType"
:
"CmdHangup"
,
...
...
@@ -394,73 +587,142 @@ pub async fn handle_agora_call(
"fromName"
:
"Server"
,
"toID"
:
user_id
,
"msgData"
:
{
"channelId"
:
""
,
"rtcToken"
:
""
}
})
.to_string
(),
&
user_id
)
.await
;
})
.to_string
(),
user_id
)
.await
;
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
}
}
}
}
}
=>
{}
_
=
cancel_rx
.recv
()
=>
println!
(
"收到取消信号,有新的人员加入到会议,会议频道号 {} 结束线程"
,
channel_id_clone
),
}
});
}
else
{
let
(
allowed
,
disallowed
):
(
Vec
<
_
>
,
Vec
<
_
>
)
=
remaining_users
.into_iter
()
.partition
(|
id
|
HOST_ENABLED_ID_SET
.contains
(
id
.as_str
()));
let
(
allowed
,
disallowed
):
(
Vec
<
_
>
,
Vec
<
_
>
)
=
remaining_users
.into_iter
()
.partition
(|
id
|
HOST_ENABLED_ID_SET
.contains
(
id
.as_str
()));
let
new_host
=
allowed
.into_iter
()
.next
()
.or
(
disallowed
.into_iter
()
.next
());
if
let
Some
(
host_id
)
=
new_host
{
let
joined
=
update_user_status
(
&
host_id
,
&
ONLINE_USERS
.get
(
&
host_id
)
.map
(|
v
|
v
.split
(
','
)
.next
()
.unwrap_or
(
"idle"
)
.to_string
())
.unwrap_or
(
"idle"
.into
()),
&
channel_id
,
true
);
let
joined
=
update_user_status
(
&
host_id
,
&
ONLINE_USERS
.get
(
&
host_id
)
.map
(|
v
|
v
.split
(
','
)
.next
()
.unwrap_or
(
"idle"
)
.to_string
())
.unwrap_or
(
"idle"
.into
()),
&
channel_id
,
true
,
);
update_redis_async
(
host_id
,
joined
);
}
}
}
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
}
}
"Connect"
=>
{
println!
(
"收到客户端Connect消息连接 {} 频道信息 {:?}"
,
from_id
,
client_message_data
);
println!
(
"收到客户端Connect消息连接 {} 频道信息 {:?}"
,
from_id
,
client_message_data
);
let
to_id
=
&
client_message_data
.to_id
;
if
let
Some
(
to_data
)
=
ONLINE_USERS
.get
(
to_id
)
.map
(|
v
|
v
.clone
())
{
let
data_split
=
to_data
.split
(
','
)
.map
(
String
::
from
)
.collect
::
<
Vec
<
_
>>
();
let
channel_id
=
data_split
[
CHANNEL_IDX
]
.clone
();
if
channel_id
.is_empty
()
{
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"对方数据出现异常,缺少channelID"
)
.await
;
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"对方数据出现异常,缺少channelID"
,
)
.await
;
return
;
}
if
let
Some
(
sender
)
=
refuse_procedure_map
.get
(
from_id
)
{
sender
.send
(())
.ok
();
}
if
let
Some
(
sender
)
=
channel_hangup_procedure_map
.get
(
&
channel_id
)
{
sender
.send
(())
.ok
();
}
if
let
Some
(
sender
)
=
refuse_procedure_map
.get
(
from_id
)
{
sender
.send
(())
.ok
();
}
if
let
Some
(
sender
)
=
channel_hangup_procedure_map
.get
(
&
channel_id
)
{
sender
.send
(())
.ok
();
}
if
!
ONLINE_USERS
.iter
()
.any
(|
e
|
e
.value
()
.split
(
','
)
.nth
(
CHANNEL_IDX
)
.unwrap_or
(
""
)
==
channel_id
&&
e
.value
()
.split
(
','
)
.nth
(
HOST_IDX
)
.unwrap_or
(
""
)
==
"1"
)
{
if
!
ONLINE_USERS
.iter
()
.any
(|
e
|
{
e
.value
()
.split
(
','
)
.nth
(
CHANNEL_IDX
)
.unwrap_or
(
""
)
==
channel_id
&&
e
.value
()
.split
(
','
)
.nth
(
HOST_IDX
)
.unwrap_or
(
""
)
==
"1"
})
{
let
initiator
=
channel_id
.split
(
'_'
)
.next
()
.unwrap_or
(
""
);
let
host_id
=
if
HOST_ENABLED_ID_SET
.contains
(
initiator
)
{
initiator
.to_string
()
}
else
{
ONLINE_USERS
.iter
()
.filter
(|
e
|
e
.value
()
.split
(
','
)
.nth
(
CHANNEL_IDX
)
.unwrap_or
(
""
)
==
channel_id
)
ONLINE_USERS
.iter
()
.filter
(|
e
|
{
e
.value
()
.split
(
','
)
.nth
(
CHANNEL_IDX
)
.unwrap_or
(
""
)
==
channel_id
})
.map
(|
e
|
e
.key
()
.clone
())
.find
(|
id
|
HOST_ENABLED_ID_SET
.contains
(
id
.as_str
()))
.unwrap_or_else
(||
ONLINE_USERS
.iter
()
.find
(|
e
|
e
.value
()
.split
(
','
)
.nth
(
CHANNEL_IDX
)
.unwrap_or
(
""
)
==
channel_id
)
.map
(|
e
|
e
.key
()
.clone
())
.unwrap_or_default
())
.unwrap_or_else
(||
{
ONLINE_USERS
.iter
()
.find
(|
e
|
{
e
.value
()
.split
(
','
)
.nth
(
CHANNEL_IDX
)
.unwrap_or
(
""
)
==
channel_id
})
.map
(|
e
|
e
.key
()
.clone
())
.unwrap_or_default
()
})
};
let
joined
=
update_user_status
(
&
host_id
,
&
ONLINE_USERS
.get
(
&
host_id
)
.map
(|
v
|
v
.split
(
','
)
.next
()
.unwrap_or
(
"idle"
)
.to_string
())
.unwrap_or
(
"idle"
.into
()),
&
channel_id
,
true
);
let
joined
=
update_user_status
(
&
host_id
,
&
ONLINE_USERS
.get
(
&
host_id
)
.map
(|
v
|
v
.split
(
','
)
.next
()
.unwrap_or
(
"idle"
)
.to_string
())
.unwrap_or
(
"idle"
.into
()),
&
channel_id
,
true
,
);
update_redis_async
(
host_id
,
joined
);
}
let
users
=
ONLINE_USERS
.iter
()
.filter
(|
e
|
e
.value
()
.split
(
','
)
.nth
(
CHANNEL_IDX
)
.unwrap_or
(
""
)
==
channel_id
&&
e
.value
()
.split
(
','
)
.nth
(
STATUS_IDX
)
.unwrap_or
(
""
)
!=
"calling"
)
let
users
=
ONLINE_USERS
.iter
()
.filter
(|
e
|
{
e
.value
()
.split
(
','
)
.nth
(
CHANNEL_IDX
)
.unwrap_or
(
""
)
==
channel_id
&&
e
.value
()
.split
(
','
)
.nth
(
STATUS_IDX
)
.unwrap_or
(
""
)
!=
"calling"
})
.map
(|
e
|
e
.key
()
.clone
())
.collect
::
<
Vec
<
_
>>
();
for
user_id
in
users
{
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
"CmdConnect"
,
"msgData"
:
{
"channelID"
:
channel_id
,
"rtcToken"
:
""
},
"fromID"
:
"0"
,
"fromName"
:
"Server"
,
"toID"
:
user_id
})
.to_string
(),
&
user_id
)
.await
;
})
.to_string
(),
&
user_id
,
)
.await
;
}
}
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
}
else
{
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"必须传递to_id"
)
.await
;
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"必须传递to_id"
)
.await
;
}
}
...
...
@@ -469,34 +731,60 @@ pub async fn handle_agora_call(
if
let
Some
(
user_data
)
=
ONLINE_USERS
.get
(
from_id
)
.map
(|
v
|
v
.clone
())
{
let
user_data_vec
=
user_data
.split
(
','
)
.map
(
String
::
from
)
.collect
::
<
Vec
<
_
>>
();
if
user_data_vec
[
HOST_IDX
]
!=
"1"
{
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"只有主持人才能踢出用户"
)
.await
;
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"只有主持人才能踢出用户"
,
)
.await
;
}
else
{
let
channel_id
=
user_data_vec
[
CHANNEL_IDX
]
.clone
();
let
users
=
get_users_by_channel
(
&
channel_id
);
for
user_id
in
users
{
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
if
user_id
==
client_message_data
.to_id
{
let
joined
=
update_user_status
(
&
user_id
,
"idle"
,
""
,
false
);
update_redis_async
(
user_id
.clone
(),
joined
);
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
"CmdHangup"
,
"msgData"
:
{
"channelID"
:
channel_id
,
"rtcToken"
:
""
},
"fromID"
:
"0"
,
"fromName"
:
"Server"
,
"toID"
:
user_id
})
.to_string
(),
&
user_id
)
.await
;
})
.to_string
(),
&
user_id
,
)
.await
;
}
else
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
"CmdKickOut"
,
"msgData"
:
{
"channelID"
:
channel_id
,
"rtcToken"
:
""
},
"toID"
:
client_message_data
.to_id
,
"fromName"
:
"Server"
,
"fromID"
:
"0"
})
.to_string
(),
&
user_id
)
.await
;
})
.to_string
(),
&
user_id
,
)
.await
;
}
}
}
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
tokio
::
spawn
(
async
move
{
notify_all_clients_to_update_online_users
()
.await
;
});
}
}
}
...
...
@@ -505,13 +793,20 @@ pub async fn handle_agora_call(
println!
(
"step - Mute - 1 收到静音通知"
);
let
to_id
=
&
client_message_data
.to_id
;
if
to_id
.is_empty
()
{
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"必须传递to_id"
)
.await
;
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"必须传递to_id"
)
.await
;
return
;
}
if
let
Some
(
user_data
)
=
ONLINE_USERS
.get
(
from_id
)
.map
(|
v
|
v
.clone
())
{
let
user_data_vec
=
user_data
.split
(
','
)
.map
(
String
::
from
)
.collect
::
<
Vec
<
_
>>
();
if
user_data_vec
[
HOST_IDX
]
!=
"1"
{
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"您不是主持人,无法静音他人"
)
.await
;
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"您不是主持人,无法静音他人"
,
)
.await
;
return
;
}
let
channel_id
=
user_data_vec
[
CHANNEL_IDX
]
.clone
();
...
...
@@ -522,10 +817,16 @@ pub async fn handle_agora_call(
"fromID"
:
to_id
,
"fromName"
:
"Server"
,
"toID"
:
to_id
})
.to_string
();
})
.to_string
();
for
user_id
in
users
{
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
json_str
.clone
(),
&
user_id
)
.await
;
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
json_str
.clone
(),
&
user_id
)
.await
;
}
}
}
...
...
@@ -536,20 +837,37 @@ pub async fn handle_agora_call(
if
let
Some
(
user_data
)
=
ONLINE_USERS
.get
(
from_id
)
.map
(|
v
|
v
.clone
())
{
let
user_data_vec
=
user_data
.split
(
','
)
.map
(
String
::
from
)
.collect
::
<
Vec
<
_
>>
();
if
user_data_vec
[
HOST_IDX
]
!=
"1"
{
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"只有主持人才有操作权限"
)
.await
;
send_error_message
(
&
target_sender_which
,
event_sender
,
from_id
,
"只有主持人才有操作权限"
,
)
.await
;
return
;
}
let
channel_id
=
user_data_vec
[
CHANNEL_IDX
]
.clone
();
let
users
=
get_users_by_channel
(
&
channel_id
);
for
user_id
in
users
{
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
"CmdMuteAll"
,
"msgData"
:
{
"channelID"
:
channel_id
,
"rtcToken"
:
""
},
"fromID"
:
"0"
,
"fromName"
:
"Server"
,
"toID"
:
user_id
})
.to_string
(),
&
user_id
)
.await
;
})
.to_string
(),
&
user_id
,
)
.await
;
}
}
}
...
...
@@ -562,14 +880,25 @@ pub async fn handle_agora_call(
let
channel_id
=
user_data_vec
[
CHANNEL_IDX
]
.clone
();
let
users
=
get_users_by_channel
(
&
channel_id
);
for
user_id
in
users
{
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
if
let
Some
(
sender
)
=
CLIENT_SENDERS
.iter
()
.find
(|
e
|
e
.key
()
.
0
==
user_id
)
.map
(|
e
|
e
.key
()
.clone
())
{
send_inside_message
(
&
sender
,
event_sender
,
serde_json
::
json!
({
"msgType"
:
client_message_data
.msg_type
.as_str
(),
"msgData"
:
{},
"fromID"
:
from_id
,
"fromName"
:
"Unknown"
,
"toID"
:
user_id
})
.to_string
(),
&
user_id
)
.await
;
})
.to_string
(),
&
user_id
,
)
.await
;
}
}
}
...
...
src/main.rs
View file @
e93a18f7
...
...
@@ -10,14 +10,22 @@ mod deport;
use
crate
::
events
::
handle_events
;
use
client
::
handle_client
;
use
config
::
config
::
STATIC_ADDR
as
addr
;
use
tokio
::
net
::
TcpListener
;
use
tokio
::
sync
::
mpsc
;
use
utils
::
utils
::
get_addr
;
#[tokio
::
main]
async
fn
main
()
{
let
listener
=
TcpListener
::
bind
(
addr
)
.await
.unwrap
();
let
bind_addr
=
match
get_addr
()
{
Ok
(
other_addr
)
=>
other_addr
,
Err
(
err
)
=>
{
eprintln!
(
"Error: {}"
,
err
);
std
::
process
::
exit
(
1
);
}
};
let
listener
=
TcpListener
::
bind
(
bind_addr
)
.await
.unwrap
();
// 创建事件通道
let
(
event_sender
,
event_receiver
)
=
mpsc
::
unbounded_channel
();
// 启动事件处理任务
...
...
src/utils/utils.rs
View file @
e93a18f7
use
std
::
collections
::
HashMap
;
use
std
::
env
;
use
std
::
net
::
SocketAddr
;
use
crate
::
config
::
config
::
STATIC_ADDR
;
pub
(
crate
)
fn
get_connection_params
(
connection_url
:
String
,
...
...
@@ -17,3 +20,27 @@ pub(crate) fn get_connection_params(
Ok
(
HashMap
::
new
())
}
}
// 获取地址的逻辑封装
pub
fn
get_addr
()
->
Result
<
String
,
Box
<
dyn
std
::
error
::
Error
>>
{
// 1. 处理命令行参数
let
mut
args
=
env
::
args
()
.skip
(
1
);
if
let
Some
(
pos
)
=
args
.position
(|
arg
|
arg
==
"--addr"
)
{
// 获取下一个参数值
return
args
.nth
(
pos
)
.ok_or
(
"--addr requires a value"
.into
())
.and_then
(|
addr
|
{
addr
.parse
::
<
SocketAddr
>
()
?
;
Ok
(
addr
)
});
}
// 2. 处理环境变量
if
let
Ok
(
env_addr
)
=
env
::
var
(
"RS_WS_ADDR"
)
{
env_addr
.parse
::
<
SocketAddr
>
()
?
;
return
Ok
(
env_addr
);
}
// 3. 返回默认值
Ok
(
STATIC_ADDR
.to_string
())
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment