Trong EzyPlatform và EzyFox Server tồn tại 3 giao thức là: TCP, UDP và Websocket. Websocket sẽ sử dụng định dạng gói tin kiểu JSON, nguyên do của việc này là Websocket được sử dụng chủ yếu cho web nên JSON sẽ dễ gỡ lỗi hơn và cũng dễ lập trình hơn cho các nhà phát triển front-end. Tuy nhiên TCP, UDP thường được sử dụng cho phần mềm chạy trên các thiết bị di động, IoT hay desktop, sẽ là cơ hội tuyệt vời để EzyPlatform và EzyFox Server đưa các kỹ thuật vào để tối ưu dung lượng gói tin.

Định dạng gói tin là gì?

Là một cách thức mô tả thành phần của một gói tin, ví dụ:

[header][body]

Đây là định dạng của một gói tin có phần đầu (header) và phần thân (body), với dữ liệu cụ thể ta có thể có:

[chiều dài = 11, kiểu = chuỗi][Hello World]

Thì phần đầu sẽ có các dữ liệu mô tả chiều dài và kiểu của phần thân, còn phần thân sẽ chứa dữ liệu thực tế.

Một ví dụ khác về định dạng gói tin dạng json:

{
     "message": "Hello World"
}

Định dạng này không có header nhưng lại yêu cầu phải có các ký tự {} để thể hiện việc bắt đầu và kết thúc gói tin.

Tại sao một gói tin lại cần định dạng?

Một thông điệp trong thực tế sẽ dễ bị chia nhỏ thành các phần khác khi gửi nhận qua mạng, ví dụ thông điệp:

Hello World

Có thể bị chia thành 2 lần gửi là Hello World. Cùng với đó server sẽ phải đợi cho một gói tin có đầy đủ thì mới được xử lý chứ không được xử lý một phần, chính vì vậy mà chúng ta sẽ cần định dạng để biết đâu là một gói tin đầy đủ, đâu là chưa.

Định dạng gói tin của EzyPlatform socket

Một gói tin của EzyPlatform và EzyFox Server socket sẽ có 2 thành phần chính:

protocol-packet-header.png
  1. Header: dùng để mô tả thông tin của gói tin.
  2. Payload: là nơi chứa thông tin thực tế của một gói tin.

Hai thành phần tuỳ chọn bao gồm:

  1. Header dự trữ: trong trường hợp 1 byte là không đủ, chúng ta có thể sử dụng thêm các byte khác để làm header.
  2. Payload Length: dùng để lưu kích thước của Payload.

Định dạng phần header

Theo tư duy thông thường chúng ta sẽ tổ chức header thế này cho tường minh:

{
    "isBigSize": true,
    "isEncrypted": true,
    "isCompressed": true,
    "isText": true,
    "isRawBytes": true,
    "isUdpHandshake": true
}

Tuy nhiên nếu mỗi ký tự là một byte thì cách này lại quá tốn, chính vì vậy mà EzyFox Server có cách tổ thức như sau:

protocol-02.png
  1. Bit đầu tiên: định nghĩa rằng gói tin này là là lớn hay nhỏ, nếu lớn thì PayLoad Length sẽ có kích thước tối đa là 4 bytes tương đương với 2^31 - 1 bytes, và nếu gói tin này là nhỏ thì PayLoad Length sẽ có kích thước tối đa là 2 bytes tương đương với 2^16-1 bytes.
  2. Bit thứ 2: định nghĩa rằng gói tin này bị mã hoá hay không
  3. Bit thứ 3: định nghĩa gói tin này có bị nén 2 không
  4. Bit thứ 4: định nghĩa gói tin này là text hay là byte array
  5. Bit thứ 5: định nghĩa gói tin này có cấu trúc không hay chỉ là mảng byte đơn thuần
  6. Bit thứ 6: định nghĩa gói tin này có phải là bản tin bắt tay của UDP hay không
  7. Bit thứ 7: dùng để dự trữ
  8. Bit thứ 8: dùng để định nghĩa rằng có 1 byte làm header nữa hay không.

Theo cách này chúng ta sẽ chỉ cần sử dụng 1 byte thay vì hàng trăm byte, ngoài ra vẫn có thể mở rộng được phần header khi chỉ cần chỉ định bit thứ 8 là 1.

Định dạng phần body

Trên thực tế EzyPlatform và EzyFox Server không bắt buộc phải sử dụng một định dạng cố định, bạn có thể tuỳ ý cài đặt định dang mà mình muốn, nhưng mặc định thì sẽ là MsgPack. Đây là một định dạng gói tin gần giống json tuy nhiên nó lại sử dụng các bit đầu của một byte để làm đặc tả thay vì chuỗi.

Ví dụ thay vì dùng 4 byte để mô tả cho giá trị integer 1 thì MsgPack dùng 1 byte duy nhất với các bit là 00000001. Đối với chuỗi Hello World thì MsgPack sẽ chỉ cần mất thêm 1 byte để mô tả về độ dài của chuỗi thay vì phải mất 2 byte cho 2 ký tự ", và chuỗi Hello World sẽ được chuyển thành byte array như sau:

[171, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

Bạn có thể tìm thấy cài đặt tại module ezyfox-msgpack.

Tổng kết

Định dạng gói tin cho EzyPlatform và EzyFox Server socket được thiết kế sao cho nó tốn ít dung lượng nhất có thể để tối ưu tốc độ gửi nhận giữa client và server. Một gói tin sẽ chỉ mất một byte cho header và phần body mặc định sẽ được sử dụng MsgPack để hỗ trợ tự động cho các nhà phát triển tối thiểu hoá dữ liệu gửi nhận qua mạng.