Trong bài viết “NHỮNG MÔN HỌC CẦN THIẾT NẾU BẠN MUỐN TRỞ THÀNH SENIOR DEVELOPER“, tôi đã nói về những môn học giúp bạn có kiến thức vững chắc, và tự tin tham gia vào bất kỳ dự án nào. Tuy nhiên sau khi đọc xong, có nhiều bạn nhắn với tôi là “anh ơi, em biết là phải học những môn đó, nhưng em lại không biết học như thế nào”. Thật sự điều này cũng tương đối khó, bởi có quá nhiều thứ để học, bạn không biết được mình phải bắt đầu từ đâu, lộ trình thế nào, làm sao đạt được hiệu quả tốt nhất, thời gian ngắn nhất.
Một trong những cách học hiệu quả nhất là bắt tay vào làm một dự án thực tế (tôi cũng có nói về điều này trong bài Một số lời khuyên cho người học IT), nhưng làm cái gì lại là một câu hỏi khác. Một trong những sai lầm của các bạn khi chọn đề tài là các bạn chọn một dự án mà bạn đã biết cách làm, điều này làm bạn mất thời gian nhưng không đạt hiệu quả. Ví dụ khi chọn đề tài là viết một hệ thống quản lý điểm sinh viên, bạn sẽ nhận ra rằng có rất nhiều thao tác trong đó chỉ là CRUD (tạo/xem/xóa/sửa) dữ liệu trong database, và thao tác bạn làm nhiều nhất đôi khi lại là cắt/dán.
Sau một hồi suy nghĩ về điều này, tôi đã chọn ra một đề tài có thể giúp các bạn vừa học OOP, design pattern (Abstract Factory, DI, IoC, Decorator, caching patterns, và nhiều nhiều nữa…), vừa liên quan đến networking (TCP/IP, HTTP), lại có cả lập trình multithread.
Đó là viết ra hẳn một Web Server.
Yêu cầu cơ bản của web server này là:
- Hỗ trợ giao thức HTTP 1.1. (có thể mở rộng để hỗ trợ HTTP/2 và HTTP/3 trong tương lai).
- Hỗ trợ HTTPS.
- Xử lý các request thông qua thread pool (không dùng cơ chế 1 thread/connection) giúp kiểm soát tài nguyên hiệu quả hơn.
- Các request sẽ được xử lý bất đồng bộ, ví dụ khi xử lý các request lớn, chúng có thể được chuyển đổi giữa các thead khác nhau, sẽ không có trường hợp một thread bị nắm giữ bởi một request.
- Hỗ trợ multi-host.
- Hỗ trợ các tài nguyên tĩnh.
- Dễ dàng nhúng vào một ứng dụng khác.
- Cơ chế plug-in giúp mở rộng hỗ trợ các tài nguyên động (giúp chạy được PHP, Javascript, .NET…), để đơn giản có thể sẽ hỗ trợ thông qua đặc tả cgi-bin.
Ngoài các yêu cầu về mặt tính năng trên, một yêu cầu quan trọng nữa là cấu trúc phải đơn giản, dễ học, dễ hiểu (vì mục đích của project này là để học). Trong lúc viết đôi lúc tôi sẽ viết một số phần hơi thừa, mục đích là để implement một pattern, hoặc để bạn học về một mảng nào đó (socket, thread…). Ngược lại có thể một số tính năng phức tạp sẽ không được implement nhằm giữ code dễ hiểu nhất. Tôi sẽ cố gắng comment và giải thích đầy đủ, để các bạn khi đọc code có thể hiểu vì sao chúng được viết như vậy.
Khi đã viết ra được một web server thì các kiến thức về web, backend và cả kiến thức nền tảng sẽ cực kỳ vững chắc.
Phiên bản đầu tiên đã được đưa lên github tại địa chỉ: https://github.com/daohainam/mini-web-server, phiên bản này đã có thể hoạt động được và hỗ trợ truy cập các tài nguyên tĩnh. Dưới đây là screenshot của trang chủ mặc nhiên khi truy cập từ trình duyệt Chrome.

Project này được viết trên .NET 7, sử dụng Visual Studio 2022.
Các bạn có thể tải về chạy thử, tạo một request và debug xem nó được xử lý thế nào, và cho repository một ngôi sao nếu thấy nó hữu ích :):
Happy coding!
Great