Chào anh em, lâu lắm rồi tôi mới ngồi lại để chia sẻ một cái “dự án nhỏ” mà tôi đã làm trong những ngày rảnh rỗi. Cái này không phải lập trình cao siêu gì đâu, chỉ là một cách để tôi luôn luôn là người biết kết quả Manchester City (Man City) sớm nhất, nhanh hơn cả mấy cái ứng dụng lớn mà anh em hay dùng.
Mấy ông hay xem bóng đá trực tuyến thì biết rồi đấy, dù là ứng dụng xịn sò cỡ nào, từ FlashScore đến ESPN, kiểu gì cũng có độ trễ. Thường là 5 đến 10 giây. Với người bình thường thì không sao, nhưng với tôi, một người phải dựa vào tin tức kết quả để làm nhiều việc khác (mà anh em tự hiểu là việc gì nhé), thì 5 giây đó là cả một thế kỷ. Tôi không chấp nhận được việc mình phải chờ đợi người khác công bố bàn thắng, trong khi lẽ ra mình phải là người công bố nó.
Bước 1: Tìm kiếm Nguồn Dữ liệu Thô
Tôi bắt đầu bằng cách phân tích. Tôi không thể dùng mấy cái trang web tin tức lớn được, vì họ còn phải biên tập, còn phải duyệt bài. Tôi cần dữ liệu thô, ngay khi bóng chạm lưới. Tôi quyết định nhắm vào các nguồn dữ liệu chuyên biệt mà các nhà cái lớn hoặc các dịch vụ cá cược sử dụng, nơi mà độ trễ được tính bằng mili giây.
Tôi dùng một công cụ nhỏ để quét và theo dõi các luồng dữ liệu công khai (dĩ nhiên là công khai, tôi không đột nhập gì đâu nhé) của một vài nhà cung cấp dịch vụ thống kê trận đấu. Ban đầu, tôi thử nghiệm với một cái bảng điểm trực tiếp đơn giản, nhưng nó lại quá chậm. Tôi phải đào sâu hơn, tìm đến những đoạn mã lệnh JavaScript hay những gói tin API ít được chú ý nhất, nơi dữ liệu bàn thắng thường được gửi đi dưới dạng một ký hiệu số, trước khi nó kịp được hiển thị đẹp đẽ trên giao diện người dùng.

Cái công đoạn mò mẫm này tốn của tôi gần một tuần lễ. Tôi phải liên tục so sánh độ trễ của từng nguồn. Nguồn nào nhanh hơn, tôi ghi chú lại. Cuối cùng, tôi chọn ra được một cặp nguồn cực kỳ ổn định, gần như là nguồn cấp dữ liệu gốc.
Bước 2: Xây dựng Bộ Lắng Nghe Thông Báo
Sau khi có nguồn, tôi bắt tay vào viết một cái mã lệnh cực kỳ tối giản. Tôi không cần giao diện đẹp, tôi chỉ cần nó chạy ổn định trên máy chủ ảo của tôi.
- Đầu tiên, tôi thiết lập để mã lệnh chỉ quan tâm đến các trận đấu có Man City tham gia. Tôi nhập vào danh sách ID trận đấu của họ mỗi cuối tuần.
- Tiếp theo, mã lệnh này làm công việc liên tục: cứ mỗi 500 mili giây (nửa giây), nó lại hỏi thăm hai nguồn dữ liệu kia. Công việc này tiêu tốn khá nhiều tài nguyên, nhưng chấp nhận được.
- Quan trọng nhất là bộ lọc. Tôi lập trình để khi thấy giá trị bàn thắng (Goal Count) của Man City thay đổi từ X thành Y, nó sẽ không làm gì khác ngoài việc kích hoạt một thông báo khẩn cấp.
Tôi mắc kẹt ở chỗ làm sao để thông báo đó đến điện thoại nhanh nhất. Email thì quá chậm. Mấy cái ứng dụng nhắn tin công cộng cũng có độ trễ riêng. Cuối cùng, tôi chọn dùng một dịch vụ đẩy thông báo (Push Notification) cực kỳ thô sơ nhưng cực kỳ hiệu quả, chỉ cần một dòng chữ ngắn gọn: “MCI GHI BÀN!” hoặc “FT MCI THẮNG!” (FT là Full Time – hết giờ).
Bước 3: Thử nghiệm và Cơn Ác Mộng Cũ
Lúc mới chạy thử, có khá nhiều lỗi. Có lần nó báo Man City ghi bàn, nhưng thực ra là đội đối thủ. Tôi phải quay lại, sửa bộ lọc để nó xác định chính xác ID của Man City. Lần khác, nó báo hết giờ khi trận đấu mới chỉ trôi qua được 10 phút vì một lỗi dữ liệu từ bên nguồn cung cấp. Tôi phải thêm cơ chế kiểm tra chéo giữa hai nguồn để đảm bảo thông tin luôn phải được xác nhận ít nhất hai lần trước khi gửi thông báo.
Tại sao tôi lại làm chuyện này một cách cực đoan như vậy? Nó bắt nguồn từ một lần tôi suýt mất trắng. Khoảng hai năm trước, tôi đặt cược một khoản tiền không nhỏ vào một trận đấu cuối mùa của Man City. Trận đó căng thẳng kinh khủng, tỉ số 0-0 kéo dài cho tới phút bù giờ cuối cùng. Tôi nhìn ứng dụng của mình, nó đứng hình. Điện thoại tôi lúc đó mạng rất yếu, gần như không tải được dữ liệu mới.
Lúc đó, tôi thấy bạn bè nhắn tin ồn ào trên nhóm chat: “Vào rồi! Man City thắng!” Nhưng ứng dụng của tôi vẫn là 0-0. Tim tôi như ngừng đập. Phải mất đến gần 20 giây sau, cái ứng dụng mới chớp lên dòng chữ “Bàn thắng” và sau đó là “Hết giờ.” Cảm giác chờ đợi trong vô vọng đó, không biết mình thắng hay thua, thật sự là một cực hình. Tôi cảm thấy mình bị phụ thuộc hoàn toàn vào tốc độ internet và cái ứng dụng ì ạch kia. Khoản tiền đó tôi thắng, nhưng trải nghiệm đó thì tôi không thể quên được.
Ngay sau vụ đó, tôi quyết tâm: tôi không thể để mình rơi vào tình cảnh đó lần nào nữa. Tôi phải xây dựng cái gì đó của riêng mình, đơn giản, nhẹ nhàng, và quan trọng nhất: chớp nhoáng.
Bước 4: Thành quả Đạt được
Sau khi hệ thống chạy ổn định, tôi đã chứng minh được nó nhanh hơn. Khi Man City ghi bàn, chuông điện thoại tôi kêu “tít” (thông báo văn bản thô) trước khi tiếng bình luận viên kịp thốt lên “VÀO!” trên sóng truyền hình trực tiếp khoảng 3 giây. So với các ứng dụng thể thao khác, tôi luôn nhận tin trước họ khoảng 5-7 giây.
Bây giờ, tôi không chỉ dùng nó cho mục đích cá nhân, mà tôi thường xuyên chia sẻ kết quả ngay lập tức lên nhóm chat. Mấy ông bạn tôi cứ nghĩ tôi là nhà tiên tri, hoặc đang ngồi cạnh sân vận động. Tôi chỉ cười. Cái công cụ nhỏ này giúp tôi không chỉ kiểm soát được thông tin mà còn lấy lại cái cảm giác chủ động, không còn phải lo lắng hay sợ hãi mỗi khi mạng chậm hay ứng dụng bị đứng hình nữa.
Đây là một dự án nhỏ nhưng mang lại hiệu quả lớn về mặt tâm lý. Anh em nào muốn tự mình kiểm soát thông tin, không muốn phụ thuộc vào ai, thì nên thử làm một cái tương tự. Nó dạy tôi nhiều điều về cách dữ liệu được luân chuyển trên mạng đấy!
