Ba khối nền tảng, một mục tiêu
Về mặt kỹ thuật, Timmy được xây dựng khá thực tế: Flutter cho ứng dụng, WebRTC cho âm thanh và video theo thời gian thực, và Firebase để điều phối. Tôi không muốn xây dựng một nền tảng khổng lồ đẩy mọi thứ qua đám mây. Mỗi phần chỉ nên biết ít nhất có thể mà vẫn hoạt động ổn định cùng các phần khác.
WebRTC: Kết nối trực tiếp, được mã hóa mặc định
WebRTC (Web Real-Time Communication) truyền âm thanh và video giữa thiết bị của bé và thiết bị của bố mẹ. Trong trường hợp tốt nhất, dữ liệu đi trực tiếp giữa hai thiết bị, theo mô hình ngang hàng, không có máy chủ truyền thông ở giữa.
Mọi kết nối WebRTC đều mặc định dùng DTLS-SRTP. Nếu ai đó chặn được các gói tin mạng, họ cũng không thể nghe hoặc xem được âm thanh, video. Mã hóa này là một phần của giao thức và không thể đơn giản tắt đi trong WebRTC.
Đây là điểm quan trọng với tôi: nội dung trong phòng bé không nên nằm trên máy chủ của tôi. Nó chỉ ở giữa các thiết bị của bạn.
Báo hiệu qua Firebase Firestore
Trước khi WebRTC có thể bắt đầu, các thiết bị cần tìm nhau và thỏa thuận cách kết nối. Phần này được gọi là báo hiệu. Timmy sử dụng Firebase Firestore, cơ sở dữ liệu đám mây của Google, cho việc này.
Chỉ dữ liệu kỹ thuật về kết nối được trao đổi:
- Đề nghị và phản hồi SDP: Mô tả khả năng của thiết bị (codec được hỗ trợ, độ phân giải, v.v.).
- Ứng viên ICE: Các đường mạng khả thi để thiết bị có thể liên lạc với nhau.
Âm thanh và video không đi vào Firebase. Firestore chỉ truyền dữ liệu kỹ thuật về kết nối. Timmy cũng mã hóa lớp báo hiệu này, vì vậy Firestore không trở thành nơi chứa SDP và ICE ở dạng rõ.
Máy chủ TURN: Khi đường kết nối trực tiếp không hoạt động
Một số mạng chặn kết nối trực tiếp, chẳng hạn như tường lửa nghiêm ngặt hoặc một số nhà mạng di động. Khi đó WebRTC cần một máy chủ chuyển tiếp TURN (Traversal Using Relays around NAT).
Timmy sẽ thử máy chủ TURN cục bộ trước, rồi dùng Cloudflare làm phương án dự phòng khi máy chủ chuyển tiếp cục bộ không khả dụng hoặc quá tải. Máy chủ chuyển tiếp chỉ chuyển tiếp các gói tin đã mã hóa. Nó không có khóa để đọc âm thanh hoặc video; mã hóa WebRTC vẫn được giữ nguyên.
Thông tin đăng nhập TURN đến từ Firebase Cloud Function và chỉ có hiệu lực trong 24 giờ. Theo tôi, thông tin đăng nhập vĩnh viễn trong ứng dụng theo dõi bé sẽ quá rủi ro.
Kết nối lân cận: Thiết bị tự động tìm thấy nhau
Để tránh các bước thiết lập rườm rà giữa thiết bị của bé và thiết bị của bố mẹ, Timmy sử dụng Nearby Connections. Google cung cấp lớp khám phá này qua Bluetooth và WiFi.
Ghép nối tự động trong Timmy không cần nhập mã thủ công: các thiết bị tự tìm thấy nhau và tìm cùng một điểm gặp để trao đổi khóa. Nếu không được, bạn có thể nhập mã gồm 4 ký tự. Mã ghép nối không bao giờ rời khỏi thiết bị; Firestore chỉ thấy một hàm băm mật mã (SHA-256) làm mã định danh tài liệu.
Xác thực ẩn danh
Timmy sử dụng Firebase Anonymous Authentication. Khi mở lần đầu, mỗi thiết bị nhận một ID tạm thời, ẩn danh. Không có tài khoản, không có địa chỉ email và không có mật khẩu. ID này chỉ dùng để áp dụng các quy tắc Firestore: chỉ thiết bị đã xác thực mới được đọc hoặc ghi dữ liệu phiên.
Kiến trúc: Ai gửi, ai nhận
Timmy có hai chế độ:
- Chế độ Bé (gửi): Thiết bị thu âm qua micrô và gửi đến thiết bị của bố mẹ bằng WebRTC. Bạn cũng có thể bật camera; khi đó video cũng được gửi trực tiếp.
- Chế độ Bố mẹ (nhận): Thiết bị nhận âm thanh và video, hiển thị luồng camera và có tính năng nhấn để nói để gửi tin nhắn thoại ngắn đến thiết bị của bé.
Các điều khiển như nhấn để nói và bật/tắt camera sử dụng một DataChannel, một kênh WebRTC khác dùng để gửi trực tiếp các tin nhắn nhỏ đã mã hóa giữa các thiết bị.
Vì sao chọn Flutter?
Flutter là framework của Google để xây dựng ứng dụng trên nhiều nền tảng. Với Timmy, điều đó có nghĩa là tôi có thể viết phần lớn logic một lần rồi dùng trên Android và iOS. Timmy hiện có trên Android, còn phiên bản iOS sắp phát hành. Ít mã trùng lặp hơn nghĩa là ít chỗ để lỗi có thể xuất hiện hơn.
Tóm tắt
Nguyên tắc kỹ thuật rất đơn giản: Timmy chỉ nên xử lý dữ liệu thật sự cần thiết. WebRTC bảo vệ nội dung truyền thông, Firebase điều phối việc thiết lập kết nối, TURN chỉ thấy các gói tin đã mã hóa, còn Nearby Connections giúp việc ghép nối bớt rườm rà.
Công nghệ tốt sẽ âm thầm hòa vào cuộc sống hằng ngày. Nó hoạt động mà không biến phòng bé thành một dự án đám mây.