CHƯƠNG 3: THIẾT KẾ VÀ XÂY DỰNG HỆ THỐNG
3.6. Hệ thống giám sát và điều khiển
3.6.1. WebSocket – giao tiếp hai chiều giữa client và server
Tìm hiểu WebSocket
WebSoket là công nghệ hỗ trợ giao tiếp hai chiều giữa client và server bằng cách sử dụng một TCP socket để tạo một kết nối hiệu quả và ít tốn kém. Mặc dù được thiết kế để chuyên sử dụng cho các ứng dụng web, lập trình viên vẫn có thể đưa chúng vào bất kì loại ứng dụng nào.
WebSockets mới xuất hiện trong HTML5, là một kỹ thuật Reverse Ajax.
WebSockets cho phép các kênh giao tiếp song song hai chiều và hiện đã được hỗ trợ trong nhiều trình duyệt (Firefox, Google Chrome và Safari). Kết nối được mở thông qua một HTTP request (yêu cầu HTTP), được gọi là liên kết WebSockets với những header đặc biệt. Kết nối được duy trì để bạn có thể viết và nhận dữ liệu bằng JavaScript như khi bạn đang sử dụng một TCP socket đơn thuần.
Dữ liệu truyền tải thông qua giao thức HTTP (thường dùng với kĩ thuật Ajax) chứa nhiều dữ liệu không cần thiết trong phần header. Một header request/response của HTTP có kích thước khoảng 871 byte, trong khi với WebSocket, kích thước này chỉ là 2 byte (sau khi đã kết nối). Vậy giả sử bạn làm một ứng dụng game có thể tới 10,000 người chơi đăng nhập cùng lúc, và mỗi giây họ sẽ gửi/nhận dữ liệu từ server.
SVTH: NGUYỄN XUÂN VINH 82 Ưu điểm
WebSockets cung cấp khả năng giao tiếp hai chiều mạnh mẽ, có độ trễ thấp và dễ xử lý lỗi. Không cần phải có nhiều kết nối như phương pháp Comet long- polling và cũng không có những nhược điểm như Comet streaming.
API cũng rất dễ sử dụng trực tiếp mà không cần bất kỳ các tầng bổ sung nào, so với Comet, thường đòi hỏi một thư viện tốt để xử lý kết nối lại, thời gian chờ timeout, các Ajax request (yêu cầu Ajax), các tin báo nhận và các dạng truyền tải tùy chọn khác nhau (Ajax long-polling và jsonp polling).
Nhược điểm
Nó là một đặc tả mới của HTML5, nên nó vẫn chưa có được sự hỗ trợ từ tất cả các trình duyệt.
Không có phạm vi yêu cầu nào. Do WebSocket là một TCP socket chứ không phải là HTTP request, nên không dễ sử dụng các dịch vụ có phạm vi-yêu cầu, như SessionInViewFilter của Hibernate. Hibernate là một framework kinh điển cung cấp một bộ lọc xung quanh một HTTP request. Khi bắt đầu một request, nó sẽ thiết lập một contest (chứa các transaction và liên kết JDBC) được ràng buộc với luồng request. Khi request đó kết thúc, bộ lọc hủy bỏ contest này.
Mô hình Socket Server và Socket Client
Chúng ta sẽ sử dụng NodeJS để lập trình cho một server được cài NodeJS nằm ngoài Internet. Máy chủ này sẽ tiếp nhận mọi yêu cầu từ Socket Client và sẽ là môi giới liên lạc giữa các Socket Client. Các Socket Client có thể là mạch ESP8266 hay là người dùng sử dụng trình duyệt web (trên điện thoại thông minh hoặc trên máy tính điện tử).
SVTH: NGUYỄN XUÂN VINH 83 Hình 3.16: Mô hình liên kết giữa Socket Server và Socket Client
Mô hình liên kết như hình 3.17 cho ta thấy chúng được chia thành 3 tầng:
Tầng cao nhất là Socket Server – gọi là tầng Server.
Tầng giữa gồm ESP8266 và trình duyệt – gọi là tầng Client.
Tầng dưới cùng là Arduino – gọi là tầng Application.
Phương thức giao tiếp, kết nối giữa Server và Client là Internet thông qua các gói dữ liệu được truyền ở dạng chuỗi JSON.
Giao tiếp giữa tầng Client và Application được thực hiện bởi cổng Serial.
Hình 3.17: Cấu trúc hoạt động của Server – Client
SVTH: NGUYỄN XUÂN VINH 84 Cấu trúc hoạt động Server – Client được chia thành 4 giai đoạn:
Giai đoạn 1:
Server tạo Socket, gán số hiệu cổng và lắng nghe yêu cầu nối kết. Server sẵn sàng phục vụ Client.socket(): Server yêu cầu tạo một socket để có thể sử dụng các dịch vụ của tầng vận chuyển.
bind(): Server yêu cầu gán số hiệu cổng (port) cho socket.
listen(): Server lắng nghe các yêu cầu nối kết từ các client trên cổng đã được gán.
Giai đoạn 2:
Client tạo Socket, yêu cầu thiết lập một nối kết với Server.
socket(): Client yêu cầu tạo một socket để có thể sử dụng các dịch vụ của tầng vận chuyển, thông thường hệ thống tự động gán một số hiệu cổng còn rảnh cho socket của Client.
connect(): Client gởi yêu cầu nối kết đến server có địa chỉ IP và Port xác định.
accept(): Server chấp nhận nối kết của client, khi đó một kênh giao tiếp ảo được hình thành, Client và server có thể trao đổi thông tin với nhau thông qua kênh ảo này.
Giai đoạn 3:
Trao đổi thông tin giữa Client và Server.
Sau khi chấp nhận yêu cầu nối kết, thông thường server thực hiện lệnh read() và nghẽn cho đến khi có thông điệp yêu cầu (Request Message) từ client gởi đến.
Server phân tích và thực thi yêu cầu. Kết quả sẽ được gởi về client bằng lệnh write().
Sau khi gởi yêu cầu bằng lệnh write(), client chờ nhận thông điệp kết quả (ReplyMessage) từ server bằng lệnh read().
SVTH: NGUYỄN XUÂN VINH 85 Giai đoạn 4:
Kết thúc phiên làm việc.
Các câu lệnh read(), write() có thể được thưc hiện nhiều lần (ký hiệu bằng hình ellipse).
Kênh ảo sẽ bị xóa khi Server hoặc Client đóng socket bằng lệnh close().