Skip to content

Commit

Permalink
changed major architecture
Browse files Browse the repository at this point in the history
  • Loading branch information
haelime committed Mar 23, 2024
1 parent 83ec295 commit da5b541
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 50 deletions.
12 changes: 3 additions & 9 deletions .github/workflows/makefile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,11 @@ jobs:
test-client:
runs-on: macos-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Set up client environment
run: |
make
# 클라이언트를 실행하기 위한 설정
# 예: 클라이언트를 빌드하고 실행하는 스크립트 실행
- name: Attatch to server
uses: test-server

- name: Run client tests
run: |
sleep 20
sleep 10
./testClient
# 클라이언트 테스트 실행
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

ircserv
testClient
log.txt

LICENSE
.vscode
13 changes: 7 additions & 6 deletions include/Channel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class Channel
public: // constructor, destructor

// when there is same channel name, the server will find the Channel object and add the client to the vector
Channel(std::string newChannelName, std::map<SOCKET_FD, ClientData *> &clientDataMap) : mFdToClientDataMap(clientDataMap), mChannelName(newChannelName){};
Channel(std::string newChannelName) : mChannelName(newChannelName){};
// Channel(std::string newChannelName, std::string newChannelPassword) : mChannelName(newChannelName), mChannelPassword(newChannelPassword) {};

// when there is no same channel name, the server will create this class and set the operatorClient as the first client and operator
Expand All @@ -46,17 +46,17 @@ class Channel
const std::string& getChannelName() const { return mChannelName; };


// void addClient(ClientData *clientData) { mFdToClientDataMap[clientData->getClientSocket()] = clientData; };
// void removeClient(ClientData *clientData) { mFdToClientDataMap.erase(clientData->getClientSocket()); };
// void addClient(ClientData *clientData) { mNameToClientDataMap[clientData->getClientSocket()] = clientData; };
// void removeClient(ClientData *clientData) { mNameToClientDataMap.erase(clientData->getClientSocket()); };

const std::map<SOCKET_FD, ClientData *> &getClients() { return mFdToClientDataMap; };
const std::map<std::string, ClientData *> &getClients() { return mNickToClientDataMap; };



private:
// prevent copy
// Channel() {};
Channel(const Channel& rhs) : mFdToClientDataMap(rhs.mFdToClientDataMap) { (void)rhs; };
Channel(const Channel& rhs) { (void)rhs; };
Channel &operator=(const Channel &rhs) { (void) rhs; return *this; };

private: // data
Expand All @@ -66,7 +66,8 @@ class Channel
std::string mMode;

// when a client joins a channel, the server will create this class and add the client to the vector
std::map<SOCKET_FD, ClientData *> &mFdToClientDataMap;
std::map<std::string, ClientData *> mNickToClientDataMap;

std::string mChannelName;
std::string mChannelPassword;
};
16 changes: 4 additions & 12 deletions include/ClientData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,9 @@ class ClientData
void setLastPingTime(time_t& time) { lastPingTime = time; };
const time_t& getLastPingTime() const { return lastPingTime; };

void addConnectedChannel(Channel* channel) { mConnectedChannels[channel->getChannelName()] = channel; };
void removeConnectedChannel(Channel* channel)
{
if (mConnectedChannels.find(channel->getChannelName()) != mConnectedChannels.end())
{
delete mConnectedChannels[channel->getChannelName()];
}
mConnectedChannels.erase(channel->getChannelName());
};

std::string& getReceivedData(void) { return mReceivedData; };

const std::map <std::string, Channel*>& getConnectedChannels() { return mConnectedChannels; };
const std::map <std::string, Channel*>& getConnectedChannels() { return mNameToConnectedChannelMap; };

public:
// should handle error if the data is too big
Expand All @@ -61,6 +51,8 @@ class ClientData
mReceivedData.clear();
};




private:
// Client's nickname, empty if not set
Expand All @@ -74,7 +66,7 @@ class ClientData
// Client's last ping time to kick if not received in 2 seconds
time_t lastPingTime;

std::map <std::string, Channel*> mConnectedChannels;
std::map <std::string, Channel*> mNameToConnectedChannelMap;

private:
std::string mReceivedData;
Expand Down
30 changes: 17 additions & 13 deletions include/Server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,41 +47,45 @@ class Server
bool checkAndSetArgv(int argc, char** argv);
void init_server(void);
void run();
void stop(){};
void stop(){}; // TODO : implement


private:
void assembleDataToMessage(std::pair<SOCKET_FD, std::string>& data);

bool isValidMessage(std::string& data);

// void connectClientToChannel(const std::string &channelName);
// void disconnectClientFromChannel(const std::string &channelName);
// void disconnectClientFromChannel(const std::string &channelName, const std::string &reason);



// server network data
private:
SOCKET_FD mServerListenSocket;
sockaddr_in mServerAddress;
socklen_t mServerAddressLength;

KQUEUE_FD mhKq;
// kernal monitor events
struct kevent mEvent;
// client events
std::vector<struct kevent> mEventVector;

// key is socket, value is ClientData, which contains all the information about the client
// when a new client connects, a new ClientData object is created and added
// when a client disconnects, the ClientData object is deleted


// arguments
private:
private: // arguments
int mPort;
std::string mServerPassword;

// server data
private:

private: // server data
// ClientData has is's channel information, so we don't need to store channel information in server
std::map<SOCKET_FD, ClientData*> mFdToClientDataMap;
std::map<std::string, Channel*> mChannelMap;

std::map<SOCKET_FD, ClientData*> mFdToEveryClientDataMap;
std::map<std::string, Channel*> mNameToEveryChannelMap;

std::queue<std::pair<SOCKET_FD, std::string> > mServerDataQueue;
std::vector<struct kevent> mEventVector;


time_t mServerStartTime;
time_t mServerLastPingTime; // to kick if not received in 2 seconds
Expand Down
44 changes: 34 additions & 10 deletions srcs/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,16 @@ void Server::run()
}
else if (mEventVector[i].flags & EV_EOF)
{
Logger::log(DEBUG, "EOF occured in kqueue, closing socket");
Logger::log(DEBUG, "EOF occured in kqueue, closing client socket and deleting clientData object");
std::perror("kevent");
close(mServerListenSocket);
assert(0);

// find the clientData
Logger::log(DEBUG, "Finding clientData object");
ClientData* clientData = mFdToEveryClientDataMap[mEventVector[i].ident]; // cuz it's map, it's O(logN)
delete clientData;
mFdToEveryClientDataMap.erase(mEventVector[i].ident);
close(mEventVector[i].ident);
// assert(0);
}
else if (mEventVector[i].flags & EVFILT_READ)
{
Expand Down Expand Up @@ -237,9 +243,9 @@ void Server::run()
Logger::log(DEBUG, "New clientData object address : " + ip);


// it's same as mFdToClientDataMap.insert(std::pair<SOCKET_FD, ClientData*>(newClientSocket, newClientData));
// it's same as mFdToEveryClientDataMap.insert(std::pair<SOCKET_FD, ClientData*>(newClientSocket, newClientData));
Logger::log(DEBUG, "Adding new clientData object to map");
mFdToClientDataMap[newClientSocket] = newClientData;
mFdToEveryClientDataMap[newClientSocket] = newClientData;
Logger::log(DEBUG, "New clientData object added to map");
}

Expand All @@ -249,7 +255,7 @@ void Server::run()
Logger::log(DEBUG, "Client is trying to send message");
// find the clientData
Logger::log(DEBUG, "Finding clientData object");
ClientData* clientData = mFdToClientDataMap[mEventVector[i].ident]; // cuz it's map, it's O(logN)
ClientData* clientData = mFdToEveryClientDataMap[mEventVector[i].ident]; // cuz it's map, it's O(logN)
if (clientData == NULL)
{
Logger::log(ERROR, "ClientData not found, closing socket");
Expand Down Expand Up @@ -280,6 +286,8 @@ void Server::run()
Logger::log(DEBUG, "IP : " + std::string(inet_ntoa(clientData->getClientAddress().sin_addr)));
Logger::log(DEBUG, "Client's Port : " + std::to_string(ntohs(clientData->getClientAddress().sin_port)));
Logger::log(DEBUG, "Received Data length : " + std::to_string(dataLength));

// should we handle IRC protocol's \r\n? I don't know
Logger::log(DEBUG, "Data : " + std::string(data, dataLength));
Logger::log(DEBUG, "Total Data : " + clientData->getReceivedData());
Logger::log(DEBUG, "-----------------------------------------");
Expand All @@ -297,7 +305,7 @@ void Server::run()

// delete clientData object
delete clientData;
mFdToClientDataMap.erase(mEventVector[i].ident);
mFdToEveryClientDataMap.erase(mEventVector[i].ident);
close(mEventVector[i].ident);
Logger::log(DEBUG, "ClientData object deleted");
continue;
Expand Down Expand Up @@ -360,8 +368,8 @@ bool Server::checkAndSetArgv(int argc, char** argv)

void Server::assembleDataToMessage(std::pair<SOCKET_FD, std::string>& data)
{
std::map<SOCKET_FD, ClientData*>::const_iterator clientDataIter = mFdToClientDataMap.find(data.first);
if (clientDataIter == mFdToClientDataMap.end())
std::map<SOCKET_FD, ClientData*>::const_iterator clientDataIter = mFdToEveryClientDataMap.find(data.first);
if (clientDataIter == mFdToEveryClientDataMap.end())
{
Logger::log(ERROR, "ClientData not found\n");
return;
Expand Down Expand Up @@ -402,4 +410,20 @@ bool Server::isValidMessage(std::string& data)

// if the data is ended with \r\n, we can make a message
return true;
};
};


// void Server::connectClientToChannel(const std::string &channelName)
// {


// }

// void Server::disconnectClientFromChannel(const std::string &channelName)
// {

// }
// void Server::disconnectClientFromChannel(const std::string &channelName, const std::string &reason)
// {

// }

0 comments on commit da5b541

Please sign in to comment.