Skip to content

Commit 02a7cea

Browse files
feat: view connected users
1 parent 4fe0d43 commit 02a7cea

1 file changed

Lines changed: 58 additions & 5 deletions

File tree

chatServer.cpp

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,22 @@ std::vector<int> sock_fds;
2828
// Keep track of all users and their sock_fds
2929
std::unordered_map<int, int> users;
3030

31+
std::unordered_map<std::string, int> usernames;
32+
3133
// Available commands
32-
const char *commands = {"whisper"};
34+
std::vector<std::string> commands = {"whisper", "view"};
3335

3436
// Mutex for sync
3537
pthread_mutex_t sock_fds_mutex PTHREAD_MUTEX_INITIALIZER;
3638
pthread_mutex_t users_mutex PTHREAD_MUTEX_INITIALIZER;
39+
pthread_mutex_t usernames_mutex PTHREAD_MUTEX_INITIALIZER;
40+
41+
// Trims strings of whitespaces
42+
std::string trim(const std::string& str) {
43+
size_t start = str.find_first_not_of(" \n\r\t");
44+
size_t end = str.find_last_not_of(" \n\r\t");
45+
return (start == std::string::npos || end == std::string::npos) ? "" : str.substr(start, end - start + 1);
46+
}
3747

3848
// Broadcasts received messages to all clients
3949
void broadcastMsg(const char *data, const char *username, int uid){
@@ -58,7 +68,40 @@ int whisperMsg(int uid, const char *username, const char *private_msg){
5868
pthread_mutex_unlock(&users_mutex);
5969

6070
if(write(sock_fd, message, sizeof(message))==-1){
61-
std::cout << "Failed to whisper message to client!" << std::endl;
71+
std::cout << "Failed to send whisper response message to client!" << std::endl;
72+
return 0;
73+
}
74+
return 1;
75+
}
76+
77+
int viewAllUsers(int sock_fd){
78+
char message[BUFLEN];
79+
bzero(message, sizeof(message));
80+
strcpy(message, "\nAll connected users:\n");
81+
82+
pthread_mutex_lock(&usernames_mutex);
83+
for(auto it: usernames){
84+
char user[100];
85+
bzero(user, sizeof(user));
86+
snprintf(user, sizeof(user), "%s : %d\n", it.first.c_str(), it.second);
87+
strcat(message, user);
88+
}
89+
pthread_mutex_unlock(&usernames_mutex);
90+
91+
if(write(sock_fd, message, strlen(message))==-1){
92+
std::cout << "Failed to send view clients response to client!" << std::endl;
93+
return 0;
94+
}
95+
return 1;
96+
}
97+
98+
int sendInvalidCommandError(int sock_fd){
99+
char message[BUFLEN];
100+
bzero(message, sizeof(message));
101+
102+
snprintf(message, sizeof(message), "Invalid command!");
103+
if(write(sock_fd, message, sizeof(message))==-1){
104+
std::cout << "Failed to send invalid command response to client!" << std::endl;
62105
return 0;
63106
}
64107
return 1;
@@ -93,17 +136,18 @@ void *handleClient(void *client){
93136

94137
// Command is received
95138
if(r_buff[0]=='/'){
96-
char command[10];
97139
char user_id[10];
98140
bzero(private_msg, sizeof(private_msg));
99141

100142
char *ptr = r_buff + 1;
101143
char *temp;
102144
temp = strtok(ptr, " ");
103145
int args = 0;
146+
std::string cmd;
104147
while(temp!=NULL){
105148
if(args==0){
106-
strcpy(command, temp);
149+
cmd = std::string(temp);
150+
cmd = trim(cmd);
107151
args++;
108152
}else if(args==1){
109153
strcpy(user_id, temp);
@@ -115,7 +159,13 @@ void *handleClient(void *client){
115159
temp = strtok(NULL, " ");
116160
}
117161

118-
whisperMsg(atoi(user_id), username, private_msg);
162+
if(cmd=="whisper"){
163+
whisperMsg(atoi(user_id), username, private_msg);
164+
}else if(cmd=="view"){
165+
viewAllUsers(sock_fd);
166+
}else{
167+
sendInvalidCommandError(sock_fd);
168+
}
119169
}else{
120170
// Message is received
121171
std::cout << username << "[" << uid << "]" << " says: " << r_buff << std::endl;
@@ -198,6 +248,9 @@ int main(int argc, char **argv){
198248
strcpy(c->username, username);
199249

200250
users[uid] = client_fd;
251+
std::string name = username;
252+
name = trim(name);
253+
usernames[name] = uid;
201254

202255
// Create a new thread for every client
203256
pthread_t tid;

0 commit comments

Comments
 (0)