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
e49f3e28
Commit
e49f3e28
authored
Feb 12, 2025
by
qlintonger xeno
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
成功解决CmdUpdateOnlineUsers的问题
parent
1996b323
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
94 additions
and
52 deletions
+94
-52
src/client.rs
+67
-21
src/events.rs
+12
-9
src/handles/close_connection.rs
+1
-10
src/handles/handshake.rs
+2
-1
src/handles/mod.rs
+3
-3
src/handles/online_users_update.rs
+0
-0
src/handles/redis.rs
+2
-6
src/main.rs
+7
-2
src/typing/message_typed.rs
+0
-0
No files found.
src/client.rs
View file @
e49f3e28
use
crate
::
config
::
config
::
STATIC_WS_PWD
;
use
crate
::
events
::{
register_client
,
ClientMessage
,
Event
};
use
crate
::
events
::{
register_client
,
ClientMessage
,
Event
,
CLIENT_SENDERS
};
use
crate
::
handles
::
close_connection
::
handle_connection_error
;
use
crate
::
handles
::
handle_messages
::
handle_other_message
;
use
crate
::
handles
::
handshake
::
handle_handshake
;
...
...
@@ -25,8 +25,12 @@ lazy_static! {
}
// 关闭之前绑定的 WebSocket 连接
async
fn
close_existing_connection
(
event_sender
:
&
UnboundedSender
<
Event
>
,
from_id
:
&
str
)
{
event_sender
.send
(
Event
::
CloseConnection
(
from_id
.to_string
()))
.unwrap
();
async
fn
close_existing_connection
(
from_id
:
&
str
)
{
{
// 移除客户端的发送者
let
mut
senders
=
CLIENT_SENDERS
.write
()
.await
;
senders
.remove
(
&
from_id
);
}
if
let
Err
(
e
)
=
remove_this_connection
(
from_id
)
.await
{
println!
(
"从 Redis 中移除用户信息时出错: {}"
,
e
);
}
...
...
@@ -75,7 +79,7 @@ pub(crate) async fn handle_client(
let
from_id_clone
=
from_id
.clone
();
// 检查 Redis 中是否已经存在该 fromId
close_existing_connection
(
&
event_sender
,
&
from_id
)
.await
;
close_existing_connection
(
&
from_id
)
.await
;
// 将该用户的信息插入到 Redis 中
if
let
Err
(
e
)
=
insert_this_connection
(
&
from_id
,
&
params
)
.await
{
...
...
@@ -86,7 +90,9 @@ pub(crate) async fn handle_client(
register_client
(
from_id
.clone
(),
center_to_client_sender
)
.await
;
// 发送新连接事件
event_sender
.send
(
Event
::
NewConnection
(
from_id
.clone
()))
.unwrap
();
event_sender
.send
(
Event
::
NewConnection
(
from_id
.clone
()))
.unwrap
();
let
mut
last_heartbeat_time
=
Instant
::
now
();
...
...
@@ -107,9 +113,14 @@ pub(crate) async fn handle_client(
if
let
Ok
(
json_str
)
=
heart_resp
(
&
from_id_clone
)
{
if
let
Err
(
e
)
=
sender
.send
(
Message
::
text
(
json_str
))
.await
{
println!
(
"发送心跳信息失败: {}"
,
e
);
{
// 移除客户端的发送者
let
mut
senders
=
CLIENT_SENDERS
.write
()
.await
;
senders
.remove
(
&
from_id
);
}
// 发送关闭连接事件
event_sender
.send
(
Event
::
CloseConnection
(
from_id_clone
.clone
()))
.unwrap
();
handle_connection_error
(
&
from_id_clone
,
&
event_sender
)
.await
;
handle_connection_error
(
&
from_id_clone
)
.await
;
break
;
}
}
...
...
@@ -119,8 +130,14 @@ pub(crate) async fn handle_client(
if
let
Err
(
e
)
=
send_online_users_and_send
(
&
mut
sender
,
&
from_id_clone
)
.await
{
println!
(
"处理在线用户列表出错了:{:?}"
,
e
);
// 发送关闭连接事件
{
// 移除客户端的发送者
let
mut
senders
=
CLIENT_SENDERS
.write
()
.await
;
senders
.remove
(
&
from_id
);
}
// 发送关闭连接事件
event_sender
.send
(
Event
::
CloseConnection
(
from_id_clone
.clone
()))
.unwrap
();
handle_connection_error
(
&
from_id_clone
,
&
event_sender
)
.await
;
handle_connection_error
(
&
from_id_clone
)
.await
;
break
;
}
},
...
...
@@ -128,8 +145,14 @@ pub(crate) async fn handle_client(
if
let
Err
(
e
)
=
handle_other_message
(
&
mut
sender
,
&
data
,
&
from_id_clone
)
.await
{
println!
(
"Failed to handle other message: {}"
,
e
);
// 发送关闭连接事件
{
// 移除客户端的发送者
let
mut
senders
=
CLIENT_SENDERS
.write
()
.await
;
senders
.remove
(
&
from_id
);
}
// 发送关闭连接事件
event_sender
.send
(
Event
::
CloseConnection
(
from_id_clone
.clone
()))
.unwrap
();
handle_connection_error
(
&
from_id_clone
,
&
event_sender
)
.await
;
handle_connection_error
(
&
from_id_clone
)
.await
;
break
;
}
}
...
...
@@ -144,21 +167,33 @@ pub(crate) async fn handle_client(
Some
(
Err
(
e
))
=>
{
println!
(
"接受客户端消息出错: {}"
,
e
);
// 发送关闭连接事件
{
// 移除客户端的发送者
let
mut
senders
=
CLIENT_SENDERS
.write
()
.await
;
senders
.remove
(
&
from_id
);
}
// 发送关闭连接事件
event_sender
.send
(
Event
::
CloseConnection
(
from_id_clone
.clone
()))
.unwrap
();
handle_connection_error
(
&
from_id_clone
,
&
event_sender
)
.await
;
handle_connection_error
(
&
from_id_clone
)
.await
;
break
;
}
None
=>
{
println!
(
"客户端断开连接"
);
// 发送关闭连接事件
{
// 移除客户端的发送者
let
mut
senders
=
CLIENT_SENDERS
.write
()
.await
;
senders
.remove
(
&
from_id
);
}
// 发送关闭连接事件
event_sender
.send
(
Event
::
CloseConnection
(
from_id_clone
.clone
()))
.unwrap
();
handle_connection_error
(
&
from_id_clone
,
&
event_sender
)
.await
;
handle_connection_error
(
&
from_id_clone
)
.await
;
break
;
}
}
}
// 处理来自事件中心的消息
maybe_msg
=
center_to_client_receiver
.recv
()
=>
{
maybe_msg
=
center_to_client_receiver
.
try_
recv
()
=>
{
if
let
Some
(
msg
)
=
maybe_msg
{
match
msg
{
ClientMessage
::
CmdUpdateOnlineUsers
=>
{
...
...
@@ -166,8 +201,14 @@ pub(crate) async fn handle_client(
if
let
Err
(
e
)
=
send_online_users_and_send
(
&
mut
sender
,
&
from_id_clone
)
.await
{
println!
(
"处理在线用户列表出错了:{:?}"
,
e
);
// 发送关闭连接事件
{
// 移除客户端的发送者
let
mut
senders
=
CLIENT_SENDERS
.write
()
.await
;
senders
.remove
(
&
from_id
);
}
// 发送关闭连接事件
event_sender
.send
(
Event
::
CloseConnection
(
from_id_clone
.clone
()))
.unwrap
();
handle_connection_error
(
&
from_id_clone
,
&
event_sender
)
.await
;
handle_connection_error
(
&
from_id_clone
)
.await
;
break
;
}
}
...
...
@@ -179,19 +220,19 @@ pub(crate) async fn handle_client(
_
=
time
::
sleep_until
(
tokio
::
time
::
Instant
::
from
(
last_heartbeat_time
+
Duration
::
from_secs
(
20
)))
=>
{
println!
(
"用户id-{} 20秒内没有发送心跳,挂断连接"
,
from_id_clone
);
// 发送关闭连接事件
{
// 移除客户端的发送者
let
mut
senders
=
CLIENT_SENDERS
.write
()
.await
;
senders
.remove
(
&
from_id
);
}
// 发送关闭连接事件
event_sender
.send
(
Event
::
CloseConnection
(
from_id_clone
.clone
()))
.unwrap
();
handle_connection_error
(
&
from_id_clone
,
&
event_sender
)
.await
;
handle_connection_error
(
&
from_id_clone
)
.await
;
break
;
}
}
}
println!
(
"断开与用户id: {},连接"
,
from_id_clone
);
// 发送关闭连接事件
event_sender
.send
(
Event
::
CloseConnection
(
from_id_clone
.clone
()))
.unwrap
();
// 从 Redis 中移除该用户的信息
if
let
Err
(
e
)
=
remove_this_connection
(
&
from_id_clone
)
.await
{
println!
(
"从 Redis 中移除用户信息时出错: {}"
,
e
);
}
}
}
else
{
println!
(
"无法获取连接参数"
);
...
...
@@ -200,8 +241,13 @@ pub(crate) async fn handle_client(
Ok
(())
}
async
fn
send_online_users_and_send
(
sender
:
&
mut
(
impl
SinkExt
<
Message
,
Error
=
Error
>
+
std
::
marker
::
Unpin
),
from_id
:
&
str
)
->
Result
<
(),
Error
>
{
let
messages
=
send_online_users_resp
()
.await
.map_err
(|
e
|
Error
::
Io
(
std
::
io
::
Error
::
new
(
std
::
io
::
ErrorKind
::
Other
,
e
)))
?
;
async
fn
send_online_users_and_send
(
sender
:
&
mut
(
impl
SinkExt
<
Message
,
Error
=
Error
>
+
std
::
marker
::
Unpin
),
from_id
:
&
str
,
)
->
Result
<
(),
Error
>
{
let
messages
=
send_online_users_resp
()
.await
.map_err
(|
e
|
Error
::
Io
(
std
::
io
::
Error
::
new
(
std
::
io
::
ErrorKind
::
Other
,
e
)))
?
;
for
(
_
,
json
)
in
messages
{
if
let
Err
(
e
)
=
sender
.send
(
Message
::
text
(
json
))
.await
{
println!
(
"发送在线用户列表消息给用户 {} 失败: {}"
,
from_id
,
e
);
...
...
src/events.rs
View file @
e49f3e28
...
...
@@ -3,7 +3,6 @@ use std::collections::HashMap;
use
std
::
sync
::
Arc
;
use
tokio
::
sync
::
mpsc
;
use
tokio
::
sync
::
RwLock
;
use
tungstenite
::
Error
;
// 定义事件类型
#[derive(Debug)]
...
...
@@ -27,9 +26,14 @@ lazy_static! {
}
// 注册客户端的发送者
pub
async
fn
register_client
(
from_id
:
String
,
center_to_client_sender
:
mpsc
::
Sender
<
ClientMessage
>
)
{
pub
async
fn
register_client
(
from_id
:
String
,
center_to_client_sender
:
mpsc
::
Sender
<
ClientMessage
>
,
)
{
let
mut
senders
=
CLIENT_SENDERS
.write
()
.await
;
println!
(
"注册客户端的发送者数量---》注册前: {:?}"
,
&
senders
.len
());
senders
.insert
(
from_id
,
center_to_client_sender
);
println!
(
"注册客户端的发送者数量---》注册后: {:?}"
,
&
senders
.len
());
}
// 处理事件的任务
...
...
@@ -37,13 +41,12 @@ pub async fn handle_events(mut receiver: mpsc::UnboundedReceiver<Event>) {
while
let
Some
(
event
)
=
receiver
.recv
()
.await
{
match
event
{
Event
::
NewConnection
(
from_id
)
=>
{
println!
(
"新连接: {}"
,
from_id
);
println!
(
"有新的连接 用户id {} 更新在线用户列表事件触发"
,
from_id
);
notify_all_clients_to_update_online_users
()
.await
;
}
Event
::
CloseConnection
(
from_id
)
=>
{
println!
(
"关闭连接: {}"
,
from_id
);
// 移除客户端的发送者
let
mut
senders
=
CLIENT_SENDERS
.write
()
.await
;
senders
.remove
(
&
from_id
);
println!
(
"有关闭的连接 用户id {} 更新在线用户列表事件触发"
,
from_id
);
notify_all_clients_to_update_online_users
()
.await
;
}
Event
::
UpdateOnlineUsers
=>
{
// 这里可以实现其他触发更新在线用户列表的逻辑
...
...
@@ -58,9 +61,9 @@ pub async fn handle_events(mut receiver: mpsc::UnboundedReceiver<Event>) {
// 通知所有客户端线程发送 CmdUpdateOnlineUsers 消息
async
fn
notify_all_clients_to_update_online_users
()
{
let
senders
=
CLIENT_SENDERS
.read
()
.await
;
for
(
_
,
sender
)
in
senders
.iter
()
{
for
(
from_id
,
sender
)
in
senders
.iter
()
{
if
let
Err
(
e
)
=
sender
.send
(
ClientMessage
::
CmdUpdateOnlineUsers
)
.await
{
println!
(
"通知客户端
更新在线用户列表失败: {:?}"
,
e
);
println!
(
"通知客户端
{} 更新在线用户列表失败: {:?}"
,
from_id
,
e
);
}
}
}
src/handles/close_connection.rs
View file @
e49f3e28
use
crate
::
events
::
Event
;
use
crate
::
handles
::
redis
::
remove_this_connection
;
use
tokio
::
sync
::
mpsc
::
UnboundedSender
;
pub
async
fn
handle_connection_error
(
from_id
:
&
str
,
event_sender
:
&
UnboundedSender
<
Event
>
,
)
{
pub
async
fn
handle_connection_error
(
from_id
:
&
str
)
{
println!
(
"开始处理用户id: {} 的连接错误"
,
from_id
);
// 发送关闭连接事件
event_sender
.send
(
Event
::
CloseConnection
(
from_id
.to_string
()))
.unwrap
();
// 从 Redis 中移除该用户的信息
if
let
Err
(
e
)
=
remove_this_connection
(
from_id
)
.await
{
println!
(
"从 Redis 中移除用户信息时出错: {}"
,
e
);
}
}
src/handles/handshake.rs
View file @
e49f3e28
...
...
@@ -7,7 +7,8 @@ pub(crate) fn handle_handshake(
static_ws_pwd
:
&
str
,
)
->
Result
<
HashMap
<
String
,
String
>
,
String
>
{
println!
(
"新客户端连接: {}"
,
req
.uri
());
let
connection_params
=
match
crate
::
utils
::
utils
::
get_connection_params
(
req
.uri
()
.to_string
())
{
let
connection_params
=
match
crate
::
utils
::
utils
::
get_connection_params
(
req
.uri
()
.to_string
())
{
Ok
(
p
)
=>
p
,
Err
(
e
)
=>
{
let
error_msg
=
format!
(
"缺少重要连接数据段: {}"
,
e
);
...
...
src/handles/mod.rs
View file @
e49f3e28
pub
mod
close_connection
;
pub
mod
handle_messages
;
pub
mod
heartbeat
;
pub
mod
handshake
;
pub
mod
redis
;
pub
mod
close_connection
;
pub
mod
heartbeat
;
pub
mod
online_users_update
;
pub
mod
redis
;
src/handles/online_users_update.rs
View file @
e49f3e28
src/handles/redis.rs
View file @
e49f3e28
use
crate
::
client
::
ONLINE_USERS
;
use
crate
::
config
::
config
::
REDIS_ADDR
;
use
lazy_static
::
lazy_static
;
use
redis
::
Client
;
use
redis
::
Commands
;
use
redis_pool
::
SingleRedisPool
;
use
std
::
collections
::
HashMap
;
use
crate
::
client
::
ONLINE_USERS
;
lazy_static!
{
static
ref
REDIS_POOL
:
SingleRedisPool
=
{
...
...
@@ -49,11 +49,7 @@ pub async fn insert_this_connection(
// callState,channelID,deviceID,fromID,hasCamera,hasMike,isHost,userCallGroup,fromName
let
user_info_str
=
format!
(
"{},{},{},{},1,1,0,0,{}"
,
"idle"
,
""
,
from_id
,
device_id
,
from_name
"idle"
,
""
,
from_id
,
device_id
,
from_name
);
if
let
Err
(
e
)
=
con
.hset
::
<&
str
,
&
str
,
&
str
,
()
>
(
"onlineUsers"
,
from_id
,
&
user_info_str
)
{
...
...
src/main.rs
View file @
e49f3e28
...
...
@@ -2,10 +2,10 @@ extern crate core;
mod
client
;
mod
config
;
mod
events
;
mod
handles
;
mod
typing
;
mod
utils
;
mod
events
;
use
crate
::
events
::
handle_events
;
use
client
::
handle_client
;
...
...
@@ -24,6 +24,11 @@ async fn main() {
let
client_event_sender
=
event_sender
.clone
();
// 创建一个用于事件中心向客户端发送消息的通道
let
(
center_to_client_sender
,
center_to_client_receiver
)
=
mpsc
::
channel
(
10
);
tokio
::
spawn
(
handle_client
(
stream
,
client_event_sender
,
center_to_client_sender
,
center_to_client_receiver
));
tokio
::
spawn
(
handle_client
(
stream
,
client_event_sender
,
center_to_client_sender
,
center_to_client_receiver
,
));
}
}
src/typing/message_typed.rs
View file @
e49f3e28
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