-
Design Pattern
- Singleton Design Pattern
- Factory Design Pattern
- Factory Method Design Pattern
- Abstract Factory Design Pattern
- Builder Design Pattern
- Prototype Design Pattern
- Object Pool Design Pattern
- Chain of Responsibility Design Pattern
- Command Design Pattern
- Interpreter Design Pattern
- Iterator Design Pattern
- Mediator Design Pattern
- Memento Design Pattern
- Observer Design Pattern
- Observer Design Pattern - Xử Lý Exception
- Strategy Design Pattern
- Template Method Design Pattern
- Visitor Design Pattern
- Null Object Design Pattern
- Adapter Design Pattern
- Bridge Design Pattern
- Composite Design Pattern
- Decorator Design Pattern
- Flyweight Design Pattern
- Proxy Design Pattern
- S.O.L.I.D
- Clean code
- Lập trình socket
- Java Core
- Multi-Thread
- Spring
- Java Web
- Memory Caching
- Message Queue
- DevOps
- Xây dựng một nền tảng
- MongoDB
- MySQL timestamp
- Properties vs yaml
- Kotlin
- Lập Trình Machine Learning với PyTorch
- Mã Nguồn Mở
- Ezy HTTP
- Free Chat
- Một số kinh nghiệm với Git
- Review cho đồng nghiệp!
- Setup Dev Environment
- Hello World
- Create a Server Project
- Handle Client Requests
- Using ezyfox-server-csharp-client
- Using ezyfox-es6-client
- Client React.js Interaction
- Build And Deploy In Local

Là JSON nhưng nhẹ hơn
Chúng ta hãy nhìn vào đối tượng json này nhé, đây là body của API trừ tiền (100đ) của user có Id là 300
{
"userId" : 300,
"transferredMoney": 100
}
Đối tượng json này tiêu tốn mất 38
bytes. Vậy có cách nào để chúng ta giảm được dung lượng của đối tượng json này không? Câu trả lời là có, chúng ta sẽ biến đối tượng json này về dạng array kiểu này (và ngầm hiểu vị trí 0 là userId
và vị trí thứ 1 là transferredMoney
):
[300, 100]
Json array này sẽ tiêu tốn 10
bytes. Vậy liệu còn cách nào để giảm tiếp dung lượng nữa không? Đó là lúc chúng ta cần đến MessagePack.
Ý tưởng ban đầu
Khi phân tích mảng json [300, 100]
ra byte array chúng ta sẽ có:
[[0, 0, 1, 44], [0, 0, 0, 100]]
Chúng ta đều nhận thấy rằng có rất nhiều byte 0
ở đây, những byte này không mang lại giá trị gì cả, nên chúng ta có thể bỏ chúng đi và chúng ta sẽ có:
[[1, 44], [100]]
Tuy nhiên việc biểu diễn trên máy tính thực tế sẽ là [1, 44, 100]
, như vậy đến bước deserialize nó sẽ bị nhầm thành số: 76900
, vậy nên chúng ta cần sử dụng tối đa 1 byte để quy định kiểu
Các kiểu dữ liệu
Với JSON, chúng ta chỉ có 6 kiểu dữ liệu: boolean, null, số, chuỗi, object, array, tuy nhiên với 1 byte (255), Messagepack có thể cung cấp cho chúng ta nhiều kiểu hơn thế
format name | first byte (in binary) | first byte (in hex) |
---|---|---|
positive fixint | 0xxxxxxx | 0x00 - 0x7f |
fixmap | 1000xxxx | 0x80 - 0x8f |
fixarray | 1001xxxx | 0x90 - 0x9f |
fixstr | 101xxxxx | 0xa0 - 0xbf |
nil | 11000000 | 0xc0 |
(never used) | 11000001 | 0xc1 |
false | 11000010 | 0xc2 |
true | 11000011 | 0xc3 |
bin 8 | 11000100 | 0xc4 |
bin 16 | 11000101 | 0xc5 |
bin 32 | 11000110 | 0xc6 |
ext 8 | 11000111 | 0xc7 |
ext 16 | 11001000 | 0xc8 |
ext 32 | 11001001 | 0xc9 |
float 32 | 11001010 | 0xca |
float 64 | 11001011 | 0xcb |
uint 8 | 11001100 | 0xcc |
uint 16 | 11001101 | 0xcd |
uint 32 | 11001110 | 0xce |
uint 64 | 11001111 | 0xcf |
int 8 | 11010000 | 0xd0 |
int 16 | 11010001 | 0xd1 |
int 32 | 11010010 | 0xd2 |
int 64 | 11010011 | 0xd3 |
fixext 1 | 11010100 | 0xd4 |
fixext 2 | 11010101 | 0xd5 |
fixext 4 | 11010110 | 0xd6 |
fixext 8 | 11010111 | 0xd7 |
fixext 16 | 11011000 | 0xd8 |
str 8 | 11011001 | 0xd9 |
str 16 | 11011010 | 0xda |
str 32 | 11011011 | 0xdb |
array 16 | 11011100 | 0xdc |
array 32 | 11011101 | 0xdd |
map 16 | 11011110 | 0xde |
map 32 | 11011111 | 0xdf |
negative fixint | 111xxxxx | 0xe0 - 0xff |
Cơ chế hoạt động
Có 2 thứ chúng ta cần quan tâm đó là chuyển dữ liệu sang byte array (serialize), và chuyển ngược byte array thành đối đối tượng (deserialize)
Serialize
Ví dụ json array [300, 100]
- Bước 1: chuyển về dạng byte array:
[[0, 0, 1, 44], [0, 0, 0, 100]]
- Bước 2: xác định kiểu, trong ví dụ chúng ta có fixarray, uint16 và fixint
- Bước 3: thêm các byte kiểu và xoá các byte 0
Kết quả chúng ta sẽ nhận được 5 bytes:
[-110, -51, 1, 44, 100]
Dạng hex sẽ là:
[0x92, 0xCD, 0x01, 0x2C, 0x64]
Deserialize
Với mảng byte array kết quả ở trên, chúng ta sẽ thực hiện từng bước:
- Đọc byte đầu tiên để xác định kiểu: ví dụ với
0x92
chúng ta biết đây làfixarray
- Đọc các byte tiếp theo để xác size của array, object hoặc string: với
fixarray
thì byte chứa kiểu dữ liệu cũng chứa luôn size (trường hợp này bằng 2) nên chúng ta có thể bỏ qua bước này - Đọc và phân tích dữ liệu dựa theo kiểu đã biết: đọc tiếp chúng ta sẽ byte
0xCD
- Lặp lại quá trình này cho đến khi hết toàn bộ mảng array thì thôi
Ví dụ
Ngày nay với sự ra đời của các thư viện thì chúng ta cũng không cần quan tâm nhiều đến cơ chế hoạt động của MessagePack nữa, chỉ cần tạo đối tượng, là vài bước là xong. Và với ezyfox-msgpack mọi chuyện cũng đơn giản như vậy.
Bạn chỉ cần định nghĩa đối tượng:
@EzyArrayBinding
public class Transfer {
private int userId;
private int balance;
}
Tạo đối tượng codec:
final EzyBindingContext bindingContext = EzyBindingContext.builder()
.scan("com.tvd12.ezyfox.example.msgpack")
.build();
final EzyEntityCodec codec = EzyBindingEntityCodec.builder()
.marshaller(bindingContext.newMarshaller())
.unmarshaller(bindingContext.newUnmarshaller())
.messageSerializer(new MsgPackSimpleSerializer())
.messageDeserializer(new MsgPackSimpleDeserializer())
.build();
Serialize đối tượng qua byte array:
final Transfer transfer = new Transfer(300, 100);
final byte[] serializedBytes = codec.serialize(transfer);
Deserialize byte array thành đối tượng:
final Transfer deserializedObj = codec.deserialize(serializedBytes, Transfer.class);
Ví dụ đầy đủ bạn có thể xem tại đây nhé
Tham khảo
-
Design Pattern
- Singleton Design Pattern
- Factory Design Pattern
- Factory Method Design Pattern
- Abstract Factory Design Pattern
- Builder Design Pattern
- Prototype Design Pattern
- Object Pool Design Pattern
- Chain of Responsibility Design Pattern
- Command Design Pattern
- Interpreter Design Pattern
- Iterator Design Pattern
- Mediator Design Pattern
- Memento Design Pattern
- Observer Design Pattern
- Observer Design Pattern - Xử Lý Exception
- Strategy Design Pattern
- Template Method Design Pattern
- Visitor Design Pattern
- Null Object Design Pattern
- Adapter Design Pattern
- Bridge Design Pattern
- Composite Design Pattern
- Decorator Design Pattern
- Flyweight Design Pattern
- Proxy Design Pattern
- S.O.L.I.D
- Clean code
- Lập trình socket
- Java Core
- Multi-Thread
- Spring
- Java Web
- Memory Caching
- Message Queue
- DevOps
- Xây dựng một nền tảng
- MongoDB
- MySQL timestamp
- Properties vs yaml
- Kotlin
- Lập Trình Machine Learning với PyTorch
- Mã Nguồn Mở
- Ezy HTTP
- Free Chat
- Một số kinh nghiệm với Git
- Review cho đồng nghiệp!
- Setup Dev Environment
- Hello World
- Create a Server Project
- Handle Client Requests
- Using ezyfox-server-csharp-client
- Using ezyfox-es6-client
- Client React.js Interaction
- Build And Deploy In Local