Giới thiệu dự án

Sự bùng nổ của các thiết bị di động thông minh (Smartphone) cùng với hạ tầng mạng băng thông rộng 4G/5G đã thay đổi căn bản phương thức giao tiếp toàn cầu. Theo thống kê từ DataReportal, hơn 78% người dùng Internet tại Việt Nam thường xuyên sử dụng các ứng dụng OTT (Over-The-Top) để liên lạc, trao đổi công việc và học tập. Tuy nhiên, các phương thức viễn thông truyền thống như SMS hay cuộc gọi di động thông thường bộc lộ nhiều hạn chế lớn về chi phí phát sinh cao khi liên lạc đường dài, thiếu tính năng tương tác đa phương tiện và không hỗ trợ làm việc nhóm linh hoạt. Đồng thời, nhiều giải pháp thương mại hiện hữu thường tích hợp quá nhiều dịch vụ phụ trợ dẫn đến dung lượng ứng dụng phình to, tiêu tốn tài nguyên phần cứng và tiềm ẩn rủi ro rò rỉ dữ liệu riêng tư.

Đồ án tốt nghiệp "Xây dựng ứng dụng nhắn tin" (SkyChat) được nghiên cứu và phát triển bởi sinh viên Nguyễn Văn Hoàn dưới sự hướng dẫn của TS. Nguyễn Tấn Thuận tại Khoa Công nghệ Số, Trường Đại học Sư phạm Kỹ thuật – Đại học Đà Nẵng (2023). Đề tài giải quyết bài toán cốt lõi: Thiết kế và hiện thực hóa một hệ thống nhắn tin tức thời (Instant Messaging) đa nền tảng, có độ trễ truyền tải cực thấp, hỗ trợ truyền thông đa phương tiện toàn diện và tích hợp bảng điều khiển quản trị tập trung.

Mục tiêu cụ thể của đồ án bao gồm:

  1. Xây dựng ứng dụng client di động đa nền tảng (Android/iOS) bằng framework Flutter với hiệu năng kết xuất đồ họa đạt mức ổn định 60 khung hình/giây (FPS).
  2. Thiết kế và triển khai hệ thống máy chủ Backend hướng sự kiện (Event-Driven) trên nền tảng Node.js, hỗ trợ giao thức kết nối thời gian thực hai chiều (Full-Duplex) qua WebSockets.
  3. Tổ chức cơ sở dữ liệu phi quan hệ NoSQL (MongoDB) tối ưu hóa việc lưu trữ, truy vấn nhanh các tài liệu phi cấu trúc như lịch sử hội thoại, trạng thái người dùng và tệp đính kèm.
  4. Hiện thực hóa hệ sinh thái tính năng hoàn chỉnh: Nhắn tin văn bản/thoại/hình ảnh/video, gọi video trực tiếp, chia sẻ định vị GPS thời gian thực, quản lý nhóm hội thoại và quản trị hệ thống (Admin Dashboard).
  5. Đảm bảo độ trễ gửi nhận gói tin văn bản đạt mức $< 100\text{ ms}$ trong điều kiện mạng tiêu chuẩn.

Phạm vi nghiên cứu tập trung vào người dùng di động tại Việt Nam, tối ưu hóa trên nền tảng hệ điều hành Android và kiến trúc triển khai máy chủ độc lập.


Phân tích và thiết kế giải pháp

Phân tích hiện trạng

Khảo sát các giải pháp nhắn tin hiện hữu trên thị trường cho thấy sự phân hóa rõ nét giữa các nền tảng:

Tiêu chí so sánh SMS Truyền thống Facebook Messenger / Zalo Đề tài SkyChat (Flutter + Node.js)
Chi phí vận hành Tính cước theo từng ký tự/tin nhắn Miễn phí (kèm quảng cáo & khai thác dữ liệu) Miễn phí, mã nguồn mở, tự chủ hạ tầng
Độ trễ truyền tải $1000\text{ ms} - 5000\text{ ms}$ (phụ thuộc sóng GSM) $150\text{ ms} - 300\text{ ms}$ $50\text{ ms} - 100\text{ ms}$ (Socket kết nối trực tiếp)
Đa phương tiện Rất hạn chế (MMS dung lượng thấp) Đầy đủ (bị nén chất lượng media) Đầy đủ (Ảnh, Video, Audio, File, GPS, Gọi Video)
Bảo mật & Kiểm soát Mã hóa cấp nhà mạng Lưu trữ đám mây tập trung của nhà cung cấp Máy chủ riêng, kiểm soát hoàn toàn CSDL MongoDB
Tiêu tốn bộ nhớ RAM Rất thấp ($< 15\text{ MB}$) Rất cao ($150\text{ MB} - 400\text{ MB}$) Tối ưu ($45\text{ MB} - 80\text{ MB}$)

Yêu cầu người dùng được phân loại và ưu tiên theo mô hình MoSCoW:

  • Must have (Bắt buộc): Xác thực tài khoản qua số điện thoại/mật khẩu, nhắn tin văn bản 1-1 và nhóm thời gian thực, gửi hình ảnh/video/tệp tin, cập nhật hồ sơ cá nhân.
  • Should have (Nên có): Gọi video trực tiếp, thu âm và gửi tin nhắn thoại (Voice message), chia sẻ vị trí GPS qua Google Maps API, bày tỏ cảm xúc (Message Reactions), thu hồi tin nhắn.
  • Could have (Có thể có): Ghim tin nhắn đầu đoạn chat, chuyển tiếp tin nhắn, chặn tài khoản người dùng, xem trạng thái hoạt động trực tuyến (Online/Offline).
  • Won't have (Chưa hỗ trợ phiên bản hiện tại): Mã hóa đầu cuối Signal Protocol đa lớp (E2EE), đồng bộ hóa sao lưu đa đám mây tự động.

Thiết kế hệ thống

Kiến trúc hệ thống được xây dựng theo mô hình Client-Server kết hợp mô hình thiết kế MVVM (Model - View - ViewModel) ở phía ứng dụng Flutter, đảm bảo tính phân tách độc lập giữa giao diện người dùng, logic điều hướng và tầng dữ liệu.

+-------------------------------------------------------------+
|                      FLUTTER CLIENT                         |
|   [Presentation: Widgets / UI Screens / State Management]   |
|   [Domain / Business Logic: MVVM Pattern & StreamControllers]|
|   [Data: dart:io, dart:async, Socket.IO Client, HTTP Client] |
+------------------------------+------------------------------+
                               |
                (HTTPS REST API & WSS Protocols)
                               |
+------------------------------v------------------------------+
|                    NODE.JS BACKEND ENGINE                   |
|   [API Gateway / Routing: Express.js REST Controllers]      |
|   [Real-time Core: Socket.IO Server / Event Handler Engine] |
|   [Services: UserAuth, ChatEngine, WebRTC Signalling]       |
|   [Middleware: JWT Authentication, Multer Upload, ErrorHandler]|
+------------------------------+------------------------------+
                               |
                  (BSON Driver / Native TCP)
                               |
+------------------------------v------------------------------+
|                 MONGODB STORAGE LAYER (NoSQL)               |
|   [Collections: Users, Conversations, Messages, CallLogs]   |
|   [GridFS / Local Media Storage: Video, Audio, Attachments] |
+-------------------------------------------------------------+

Danh mục công nghệ và phiên bản sử dụng:

  • Client: Flutter SDK v3.10.x, Dart Language v3.0.x (Dart VM với engine đồ họa Skia, hỗ trợ biên dịch AOT/JIT).
  • Server: Node.js v18.16.x LTS (V8 JavaScript Engine, thư viện bất đồng bộ libUV), Express.js v4.18.x.
  • Real-time Protocol: Socket.IO v4.6.x (Engine.IO WebSocket transport).
  • Database: MongoDB v6.0.x Community Server, MongoDB Compass v1.38.x.
  • Bảo mật: JSON Web Token (JWT) cho Stateless Authentication, Thuật toán Bcrypt (Salt rounds = 10) băm mật khẩu.

Thiết kế mô hình dữ liệu MongoDB (NoSQL Document Structure):

{
  "_id": "ObjectId('6485a12f9b1d8c234a5e001a')",
  "conversationId": "ObjectId('6485a0aa9b1d8c234a5e0002')",
  "senderId": "ObjectId('64859f129b1d8c234a5e0001')",
  "type": "media", 
  "content": {
    "text": "Vị trí hiện tại của tôi",
    "mediaUrl": "https://cdn.skychat.local/uploads/loc_1686481200.png",
    "location": {
      "latitude": 16.0738,
      "longitude": 108.1499,
      "address": "48 Cao Thắng, Hải Châu, Đà Nẵng"
    }
  },
  "reactions": [
    { "userId": "ObjectId('64859f559b1d8c234a5e0005')", "emoji": "❤️" }
  ],
  "isPinned": false,
  "isRevoked": false,
  "createdAt": "2023-06-11T09:40:00.125Z"
}

Thiết kế giao diện lập trình ứng dụng (API Endpoints) và sự kiện thời gian thực:

  • POST /api/v1/auth/register: Đăng ký tài khoản mới với số điện thoại và mật khẩu.
  • POST /api/v1/auth/login: Xác thực tài khoản, tạo và cấp phát JWT Bearer Token.
  • GET /api/v1/users/contacts: Truy xuất danh bạ bạn bè và danh sách nhóm tham gia.
  • POST /api/v1/media/upload: Tiếp nhận tệp tin đa phương tiện đa định dạng qua Multer.
  • WebSocket Events: connection, join_room, send_message, receive_message, reaction_update, message_revoked, call_user, call_accepted, call_ended.

Methodology

Đồ án được triển khai theo quy trình phát triển phần mềm linh hoạt (Agile Scrum) rút gọn, chia làm 4 giai đoạn chính (Milestones) từ 02/2023 đến 06/2023:

  1. Khảo sát & Đặc tả (Tuần 1 - 3): Thu thập yêu cầu nghiệp vụ, xây dựng 24 sơ đồ ca sử dụng (Use-Case Diagrams), biểu đồ hoạt động (Activity Diagrams) và biểu đồ tuần tự (Sequence Diagrams).
  2. Thiết kế Kiến trúc & Cơ sở dữ liệu (Tuần 4 - 6): Thiết kế sơ đồ thực thể quan hệ ERD, thiết lập cấu trúc NoSQL Collections trên MongoDB, thiết kế Wireframe/Mockup giao diện.
  3. Hiện thực hóa mã nguồn (Tuần 7 - 13): Xây dựng Node.js WebSocket Engine, xây dựng UI Components bằng Flutter, tích hợp Camera API, Audio Recorder API và Google Maps Location SDK.
  4. Kiểm thử, Đánh giá & Hoàn thiện (Tuần 14 - 16): Thực hiện kiểm thử đơn vị (Unit Test), kiểm thử tích hợp (Integration Test), đo lường độ trễ mạng và xuất bản báo cáo tốt nghiệp.

Implementation và kết quả

Development process

Quá trình phát triển tập trung vào việc xử lý các luồng dữ liệu bất đồng bộ (Asynchronous Streams) giữa Flutter Client và Node.js Engine.

Mã nguồn Node.js xử lý sự kiện tin nhắn thời gian thực và ghi nhận cơ sở dữ liệu:

const io = require('socket.io')(server, {
  cors: { origin: "*", methods: ["GET", "POST"] }
});
const Message = require('./models/Message');

io.on('connection', (socket) => {
  socket.on('join_room', (roomId) => {
    socket.join(roomId);
  });

  socket.on('send_message', async (data) => {
    try {
      const { conversationId, senderId, type, content } = data;
      const newMessage = new Message({
        conversationId,
        senderId,
        type,
        content,
        createdAt: new Date()
      });
      const savedMessage = await newMessage.save();
      
      // Phát tín hiệu tới toàn bộ thành viên trong phòng hội thoại
      io.to(conversationId).emit('receive_message', savedMessage);
    } catch (err) {
      socket.emit('error_message', { error: 'Không thể truyền tin nhắn' });
    }
  });

  socket.on('revoke_message', async ({ messageId, conversationId }) => {
    await Message.findByIdAndUpdate(messageId, { isRevoked: true, content: { text: "Tin nhắn đã bị thu hồi" } });
    io.to(conversationId).emit('message_revoked', { messageId });
  });
});

Mã nguồn Flutter Dart quản lý luồng tin nhắn qua StreamController và kết nối Socket:

import 'dart:async';
import 'package:socket_io_client/socket_io_client.dart' as IO;

class ChatRepository {
  late IO.Socket _socket;
  final _messageStreamController = StreamController<Map<String, dynamic>>.broadcast();

  Stream<Map<String, dynamic>> get messageStream => _messageStreamController.stream;

  void initializeSocket(String serverUrl, String userToken) {
    _socket = IO.io(serverUrl, IO.OptionBuilder()
      .setTransports(['websocket'])
      .enableAutoConnect()
      .setExtraHeaders({'Authorization': 'Bearer $userToken'})
      .build());

    _socket.onConnect((_) => print('Connected to Chat Server'));

    _socket.on('receive_message', (data) {
      _messageStreamController.sink.add(Map<String, dynamic>.from(data));
    });
  }

  void sendMessage(String conversationId, String senderId, String text) {
    _socket.emit('send_message', {
      'conversationId': conversationId,
      'senderId': senderId,
      'type': 'text',
      'content': {'text': text},
    });
  }

  void dispose() {
    _messageStreamController.close();
    _socket.disconnect();
  }
}

Testing và validation

Hệ thống đã trải qua quá trình kiểm thử toàn diện với các kịch bản thực nghiệm:

Kịch bản kiểm thử Phương pháp Kết quả thực tế Trạng thái
Xác thực JWT & Session Postman Test Runner (500 requests) Thành công 100%, từ chối 100% token hết hạn Đạt
Độ trễ gửi nhận tin nhắn WebSocket Benchmark tool Trung bình $68\text{ ms}$ trên mạng 4G Viettel Đạt
Truyền tệp hình ảnh/video Tải lên tệp dung lượng $5\text{ MB} - 25\text{ MB}$ Băng thông truyền tải đạt $3.2\text{ MB/s}$, không nghẽn luồng UI Đạt
Cuộc gọi Video 1-1 WebRTC P2P Signalling Độ trễ âm thanh/hình ảnh $< 180\text{ ms}$, video chuẩn HD Đạt
Tải đồng thời (Load Test) Apache JMeter (1.000 kết nối đồng thời) Server duy trì CPU $< 35%$, RAM tiêu thụ $< 450\text{ MB}$ Đạt

Tỷ lệ bao phủ mã nguồn (Code Coverage) đạt 88.4% ở tầng Backend API và 85.2% tại các Components cốt lõi của Flutter Client.

Kết quả đạt được

Đồ án hoàn thành 100% các tính năng đã đăng ký trong đề cương nghiên cứu:

  • Xây dựng hoàn chỉnh 24 Use-cases: Gửi nhận văn bản, hình ảnh, video, âm thanh thu âm trực tiếp, chia sẻ vị trí qua Google Maps, phản hồi tin nhắn (Reply), thả biểu tượng cảm xúc (Reactions), thu hồi tin nhắn hai chiều, gọi video trực tiếp, ghim tin nhắn, chặn tài khoản và quản lý nhóm trò chuyện.
  • Xây dựng cổng thông tin quản trị Web Dashboard dành cho Admin để theo dõi thống kê người dùng, quản lý báo cáo vi phạm và quản lý danh sách phòng chat nhóm.

Đổi mới và đóng góp

  1. Ứng dụng cơ chế kết xuất đồ họa Skia Rendering Engine của Flutter: Khác với các giải pháp lai (Hybrid) dựa trên WebView như Cordova hay Ionic, Flutter biên dịch mã nguồn Dart trực tiếp sang mã máy AOT (Ahead-of-Time). Điều này giúp loại bỏ hoàn toàn cầu nối JavaScript Bridge, tăng tốc độ dựng hình đạt mốc 60 FPS ổn định, giảm tải 34% mức tiêu thụ năng lượng của thiết bị di động khi thực hiện các tác vụ cuộn danh sách tin nhắn dung lượng lớn.
  2. Mô hình định tuyến đa định dạng thời gian thực (Unified Payload Protocol): Đề tài thiết kế một cấu trúc gói tin thống nhất trên nền tảng Socket.IO, cho phép hệ thống nhận diện tự động và xử lý đồng nhất mọi loại dữ liệu (Văn bản, File nhị phân, Tọa độ địa lý GPS, Tín hiệu điều phối WebRTC) mà không cần cấu hình thêm các cổng kết nối phụ.
  3. Tối ưu hóa kiến trúc phi quan hệ Document-based cho ứng dụng trò chuyện: Khai thác tối đa khả năng mở rộng linh hoạt của MongoDB, phân chia các Collection theo cơ chế phi chuẩn hóa (Denormalization) hợp lý, giúp giảm thiểu 45% số lượng truy vấn phức tạp (Lookup/Join) so với các hệ CSDL quan hệ truyền thống (RDBMS).

Ứng dụng thực tế và triển khai

Kịch bản ứng dụng thực tế

  • Mạng truyền thông nội bộ doanh nghiệp/trường học: Triển khai làm hệ thống liên lạc an toàn, không lo ngại việc rò rỉ dữ liệu ra các nền tảng mạng xã hội thương mại của bên thứ ba.
  • Module tích hợp CSKH (Customer Support Chat): Tích hợp phần lõi Socket Server và Chat Component vào các ứng dụng thương mại điện tử hoặc dịch vụ đặt vé trực tuyến.

Hướng dẫn triển khai hệ thống (Deployment Architecture)

# 1. Khởi chạy cơ sở dữ liệu MongoDB
sudo systemctl start mongod
sudo systemctl enable mongod

# 2. Cài đặt biến môi trường và chạy Backend Node.js với PM2 Cluster Mode
cd /var/www/skychat-backend
npm install --production
export NODE_ENV=production
export PORT=5000
export MONGO_URI="mongodb://localhost:27017/skychat"
export JWT_SECRET="SKyChat_Secure_Key_2023"
pm2 start server.js -i max --name "skychat-api"

# 3. Biên dịch ứng dụng Flutter sang Android App Bundle (AAB) hoặc APK
cd /home/developer/skychat-flutter
flutter clean
flutter pub get
flutter build apk --release --split-per-abi

Hệ thống được cấu hình chạy phía sau Nginx Reverse Proxy hỗ trợ chứng chỉ SSL/TLS Let's Encrypt, kích hoạt giao thức HTTP/2 và cơ chế nâng cấp kết nối WebSocket (proxy_set_header Upgrade $http_upgrade;).


Hạn chế và hướng phát triển

Hạn chế kỹ thuật hiện tại

  • Giải pháp gọi video hiện thời sử dụng mô hình kết nối ngang hàng P2P (Peer-to-Peer) thuần túy; khi số lượng thành viên trong cuộc gọi nhóm vượt quá 4 người sẽ xuất hiện hiện tượng thắt nút cổ chai băng thông mạng phía máy khách.
  • Hệ thống chưa tích hợp thuật toán mã hóa đầu cuối phân tán (End-to-End Encryption - Signal Protocol) để tự động mã hóa gói tin trực tiếp từ thiết bị gửi trước khi chuyển qua máy chủ.

Hướng phát triển tương lai

  • Tích hợp máy chủ đa phương tiện chuyên dụng (SFU - Selective Forwarding Unit) như MediaSoup hoặc Janus Gateway để hỗ trợ hội nghị truyền hình nhóm chất lượng cao lên đến 50 người đồng thời.
  • Nghiên cứu và hiện thực hóa giao thức mã hóa Signal Protocol nhằm nâng cao tính riêng tư cấp độ quân sự cho người dùng.
  • Ứng dụng mô hình AI (Large Language Models) để xây dựng trợ lý ảo tóm tắt nội dung các cuộc thảo luận nhóm dài và hỗ trợ kiểm duyệt tự động các nội dung độc hại.

Đối tượng hưởng lợi

  • Sinh viên & Học viên ngành CNTT: Tiếp cận tài liệu tham khảo thực chiến về cách kết hợp kiến trúc Fullstack hiện đại giữa Flutter, Node.js và MongoDB; nắm vững kỹ thuật lập trình bất đồng bộ với Dart Streams và Socket.IO.
  • Lập trình viên phát triển ứng dụng di động: Khai thác các mẫu thiết kế kiến trúc (MVVM, State Management), giải pháp xử lý bộ nhớ đệm (Cache) cho hình ảnh/video và cơ chế đồng bộ dữ liệu thời gian thực.
  • Doanh nghiệp vừa và nhỏ (SMEs): Sở hữu một giải pháp mã nguồn mở hoàn chỉnh có thể tự lưu trữ (Self-hosted) trên hạ tầng máy chủ riêng, tiết kiệm hàng ngàn USD chi phí bản quyền dịch vụ truyền thông của bên thứ ba mỗi năm.
  • Nhà nghiên cứu học thuật: Cung cấp số liệu thực nghiệm đo lường độ trễ mạng và hiệu năng kết xuất đồ họa khi so sánh giữa công nghệ Native, Hybrid và Flutter AOT Engine.

Câu hỏi thường gặp

1. Yêu cầu phần cứng và phần mềm tối thiểu để triển khai hệ thống SkyChat là gì?

  • Phía Máy chủ (Server): CPU 2 vCPU, RAM $2\text{ GB}$, ổ cứng SSD tối thiểu $20\text{ GB}$, hệ điều hành Ubuntu Linux 20.04/22.04 LTS, Node.js v16+ và MongoDB v5+.
  • Phía Máy khách (Client): Điện thoại thông minh chạy hệ điều hành Android 6.0 (Marshmallow - API Level 23) trở lên hoặc iOS 12.0 trở lên, bộ nhớ RAM khả dụng tối thiểu $512\text{ MB}$.

2. Hệ thống xử lý bài toán mở rộng quy mô (Scalability) khi lượng người dùng tăng đột biến như thế nào?

Để mở rộng hệ thống phục vụ hơn 50.000 kết nối đồng thời:

  • Phía Socket Server: Sử dụng Redis Pub/Sub Adapter để liên kết nhiều Node.js instances chạy song song phía sau bộ cân bằng tải Nginx (Load Balancer).
  • Phía Cơ sở dữ liệu: Triển khai mô hình MongoDB Replica Set kết hợp phân vùng dữ liệu (Sharding) theo khóa conversationId.

3. Làm thế nào để tích hợp SkyChat với hệ thống phần mềm nghiệp vụ sẵn có?

SkyChat cung cấp hệ thống RESTful API chuẩn mở định dạng JSON. Doanh nghiệp chỉ cần gọi API xác thực (/api/v1/auth) và sử dụng các Webhook Events từ máy chủ để đồng bộ tài khoản người dùng từ hệ thống ERP/CRM nội bộ một cách nhanh chóng.

4. Chi phí vận hành và bảo trì hệ thống định kỳ ước tính bao nhiêu?

Nhờ sử dụng 100% công nghệ mã nguồn mở miễn phí (Flutter, Node.js, MongoDB Community), chi phí vận hành duy nhất là tiền thuê hạ tầng Cloud VPS (khoảng 15 - 30 USD/tháng cho quy mô 5.000 người dùng tích cực hàng ngày - DAU).

5. Dữ liệu tập tin, video và vị trí người dùng được bảo vệ như thế nào?

Tất cả các kết nối từ client đến server đều bắt buộc sử dụng giao thức bảo mật SSL/TLS (HTTPS/WSS). Các tệp tin tải lên được phân mảnh, đặt tên ngẫu nhiên theo mã băm UUIDv4, lưu trữ phân quyền và chỉ có thể truy xuất thông qua các đường dẫn có chữ ký số xác thực (Signed URLs) với thời gian sống hữu hạn (TTL).


Kết luận

Đồ án tốt nghiệp "Xây dựng ứng dụng nhắn tin" của sinh viên Nguyễn Văn Hoàn (Trường Đại học Sư phạm Kỹ thuật – Đại học Đà Nẵng, 2023) đã chứng minh tính khả thi, độ tin cậy và hiệu năng vượt trội của sự kết hợp giữa Flutter, Node.js và MongoDB trong việc xây dựng hệ sinh thái truyền thông thời gian thực. Đề tài không chỉ hoàn thành xuất sắc toàn bộ các mục tiêu lý thuyết và thực tiễn đề ra với 24 ca sử dụng hoàn chỉnh, mà còn mang lại giá trị ứng dụng cao cho cộng đồng lập trình viên và các tổ chức có nhu cầu tự chủ hạ tầng liên lạc số. Mã nguồn và kiến trúc đồ án là tài liệu tham khảo giá trị cho các nghiên cứu ứng dụng tiếp theo trong lĩnh vực truyền thông đa phương tiện trên nền tảng di động.