-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add client command #361
Changes from 17 commits
5872ec2
d51f490
aca9308
dd6b675
a768d80
21b5729
80c89ec
31b38a5
a763efa
9f0501b
1fcdd06
74cef50
47e23d6
d5a5787
7b3d95e
3f092e9
2cfd085
1acf057
4462256
0ee023f
d0ec6f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
#include "client_map.h" | ||
#include "log.h" | ||
|
||
namespace pikiwidb { | ||
|
||
uint32_t ClientMap::GetAllClientInfos(std::vector<ClientInfo>& results) { | ||
// client info string type: ip, port, fd. | ||
std::shared_lock<std::shared_mutex> client_map_lock(client_map_mutex_); | ||
for (auto& [id, client_weak] : clients_) { | ||
if (auto client = client_weak.lock()) { | ||
results.emplace_back(client->GetClientInfo()); | ||
} | ||
} | ||
return results.size(); | ||
} | ||
|
||
bool ClientMap::AddClient(int id, std::weak_ptr<PClient> client) { | ||
std::unique_lock client_map_lock(client_map_mutex_); | ||
if (clients_.find(id) == clients_.end()) { | ||
clients_.insert({id, client}); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
ClientInfo ClientMap::GetClientsInfoById(int id) { | ||
std::shared_lock client_map_lock(client_map_mutex_); | ||
if (auto it = clients_.find(id); it != clients_.end()) { | ||
if (auto client = it->second.lock(); client) { | ||
return client->GetClientInfo(); | ||
} | ||
} | ||
ERROR("Client with ID {} not found in GetClientsInfoById", id); | ||
return ClientInfo::invalidClientInfo; | ||
} | ||
|
||
bool ClientMap::RemoveClientById(int id) { | ||
std::unique_lock client_map_lock(client_map_mutex_); | ||
if (auto it = clients_.find(id); it != clients_.end()) { | ||
clients_.erase(it); | ||
INFO("Removed client with ID {}", id); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
bool ClientMap::KillAllClients() { | ||
std::vector<std::shared_ptr<PClient>> clients_to_close; | ||
{ | ||
std::shared_lock<std::shared_mutex> client_map_lock(client_map_mutex_); | ||
for (auto& [id, client_weak] : clients_) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 有个疑问,这里close掉client不需要从这个map里去除吗? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 我之前是在 tcp_client 的disconnect 回调函数里面从map去掉对应的client。感觉改成在这里直接删除确实更好点,我来改一下 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 刚才仔细想了一下,这里之所以在回调函数里面,是因为存在客户端主动关闭连接的情况。这时候就需要在回调函数里面去删除map里面的记录。 |
||
if (auto client = client_weak.lock()) { | ||
clients_to_close.push_back(client); | ||
} | ||
} | ||
} | ||
for (auto& client : clients_to_close) { | ||
client->Close(); | ||
} | ||
return true; | ||
} | ||
|
||
bool ClientMap::KillClientByAddrPort(const std::string& addr_port) { | ||
std::shared_ptr<PClient> client_to_close; | ||
{ | ||
std::shared_lock<std::shared_mutex> client_map_lock(client_map_mutex_); | ||
for (auto& [id, client_weak] : clients_) { | ||
if (auto client = client_weak.lock()) { | ||
std::string client_ip_port = client->PeerIP() + ":" + std::to_string(client->PeerPort()); | ||
if (client_ip_port == addr_port) { | ||
client_to_close = client; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
if (client_to_close) { | ||
client_to_close->Close(); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
bool ClientMap::KillClientById(int client_id) { | ||
std::shared_ptr<PClient> client_to_close; | ||
{ | ||
std::shared_lock<std::shared_mutex> client_map_lock(client_map_mutex_); | ||
if (auto it = clients_.find(client_id); it != clients_.end()) { | ||
if (auto client = it->second.lock()) { | ||
client_to_close = client; | ||
} | ||
} | ||
} | ||
if (client_to_close) { | ||
INFO("Closing client with ID {}", client_id); | ||
client_to_close->Close(); | ||
INFO("Client with ID {} closed", client_id); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
} // namespace pikiwidb |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#pragma once | ||
|
||
#include <map> | ||
#include <memory> | ||
#include <shared_mutex> | ||
#include <string> | ||
#include "client.h" | ||
|
||
namespace pikiwidb { | ||
class ClientMap { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个 |
||
private: | ||
ClientMap() = default; | ||
// 禁用复制构造函数和赋值运算符 | ||
|
||
private: | ||
std::map<int, std::weak_ptr<PClient>> clients_; | ||
std::shared_mutex client_map_mutex_; | ||
|
||
public: | ||
static ClientMap& getInstance() { | ||
static ClientMap instance; | ||
return instance; | ||
} | ||
|
||
ClientMap(const ClientMap&) = delete; | ||
ClientMap& operator=(const ClientMap&) = delete; | ||
|
||
// client info function | ||
pikiwidb::ClientInfo GetClientsInfoById(int id); | ||
uint32_t GetAllClientInfos(std::vector<ClientInfo>& results); | ||
|
||
bool AddClient(int id, std::weak_ptr<PClient>); | ||
|
||
bool RemoveClientById(int id); | ||
|
||
bool KillAllClients(); | ||
bool KillClientById(int client_id); | ||
bool KillClientByAddrPort(const std::string& addr_port); | ||
}; | ||
|
||
} // namespace pikiwidb |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
建议:改进添加客户端的方法。
建议在插入客户端之前检查
client
是否有效。