1. EventLoop.hpp
Lớp này đóng vai trò theo dõi socket và lập lịch tác vụ. Dưới đây là các biến thành viên chính:
// Mảng chứa sự kiện từ epoll_wait
std::vector danhSachSuKien;
// File descriptor của epoll
int epollFd;
// Kênh đánh thức epoll_wait
std::unique_ptr kenhDanhThuc;
// Trạng thái luồng
std::atomic_bool dangChoi;
std::atomic_bool daDanhThuc;
// Danh sách hàm bất đồng bộ
std::mutex khoaDanhSachHam;
std::vector<UserFunctor> danhSachHamAsync;
std::vector<UserFunctor> danhSachHamSaoChep;
// Hàm thực thi sau khi epoll_wait
std::vector<UserFunctor> danhSachHamSauLoop;
// Thông tin luồng
std::once_flag coKhoiTaoID;
std::atomic_bool daKhoiTaoID;
current_thread::THREAD_ID_TYPE idLuong;
// Bộ quản lý định thời
brynet::base::TimerMgr::Ptr boDinhThoi;
// Ánh xạ socket và kết nối
std::unordered_map danhSachKetNoi;
Hàm vòng lặp chính
void vongLap(int64_t miliGiay)
{
khoiTaoIDLuong();
kiemTraLuong();
if (!danhSachHamSauLoop.empty())
{
miliGiay = 0;
}
int soLuong = epoll_wait(epollFd, danhSachSuKien.data(), danhSachSuKien.size(), miliGiay);
dangChoi = false;
for (int i = 0; i < soLuong; ++i)
{
auto kenh = (Channel*) (danhSachSuKien[i].data.ptr);
auto suKien = danhSachSuKien[i].events;
if (suKien & EPOLLRDHUP)
{
kenh->nhanDuLieu(true);
kenh->dongKetNoi();
continue;
}
if (suKien & EPOLLIN)
{
kenh->nhanDuLieu(false);
}
if (suKien & EPOLLOUT)
{
kenh->guiDuLieu();
}
}
daDanhThuc = false;
dangChoi = true;
xuLyHamAsync();
xuLyHamSauLoop();
if (soLuong == danhSachSuKien.size())
{
dieuChinhKichThuoc(danhSachSuKien.size() + 128);
}
boDinhThoi->thucHien();
}
2. TcpConnection.hpp
Lớp quản lý phiên kết nối TCP với các callback sau:
// Callback khi kết nối thành công
using EnterCallback = std::function;
// Callback nhận dữ liệu
using DataCallback = std::function;
// Callback ngắt kết nối
using DisconnectedCallback = std::function;
// Callback sau khi gửi dữ liệu
using PacketSendedCallback = std::function;
// Callback khi vượt mức dữ liệu
using HighWaterCallback = std::function;
Hàm xử lý dữ liệu
void xuLyDuLieuNhan()
{
if (hamXuLyDuLieu != nullptr && demNhan.coDuLieu())
{
auto docGia = brynet::base::BasePacketReader(demNhan.layConTro(), demNhan.layDoDai());
hamXuLyDuLieu(docGia);
size_t daXuLy = docGia.layViTri();
demNhan.tienConTro(daXuLy);
}
}
3. TCPServiceDetail.hpp
Hàm khởi tạo luồng worker
std::vector khoiTaoLuongWorker(size_t soLuong, FrameCallback ham = nullptr)
{
std::vector vongLap;
auto coChay = std::make_shared<bool>(true);
auto wg = brynet::base::WaitGroup::Tao();
for (int i = 0; i < soLuong; ++i)
{
auto vongLapMoi = std::make_shared<EventLoop>();
vongLap.push_back(vongLapMoi);
wg->them(1);
vongLapDuLieu.push_back(IOLoopData::Tao(vongLapMoi,
std::make_shared([=]() {
vongLapMoi->ganLuongHienTai();
wg->hoanTat();
while (*coChay)
{
vongLapMoi->vongLap(sThoiGianMacDinh);
if (ham != nullptr)
{
ham(vongLapMoi);
}
}
})));
}
wg->cho();
return vongLap;
}