Home > Flash/Flex/AIR > Gzip encoding và Adobe AIR

Gzip encoding và Adobe AIR

Gzip là gì:

Gzip nói một cách đơn giản, nôm na, hay “túm quần” lại nó chỉ là 1 chuẩn nén theo một thuật toán của ông bác học nào đó tìm ra, mục đích là làm giảm kích thướt của dữ liệu để tăng tốc độ đường truyền hay tiết kiệm không gian lưu trữ. Hiểu tới đây cũng đủ xài rồi. Còn muốn nhức đầu thêm chút thì chúng ta cùng nói sơ về nén và gzip bên dưới:

Có thể phân chia thuật toán nén theo 2 dạng: nén bảo tồn và nén thất thoát (Lossless và lossy compression)
Nén bảo tồn (lossless compression): cho phép dữ liệu nén có thể được khôi phục chính xác dữ liệu gốc. Thuật toàn này thường được dùng cho các chuẩn nén winrar, winzip, gzip…
Nén thất thoát (lossy compression): trong quá trình nén dữ liệu gốc có thể bị thất thoát 1 phần để cho ra dữ liệu nén và dữ liệu nén không có khả năng khôi phục chính xác dữ liệu gốc, nhưng chất lượng dữ liệu nén có thể tương tự, gần giống dữ liệu gốc, đủ để có ích trong một số trường hợp. Có lẽ nghe thì hơi vô lý (có ai muốn mình bị mất mát gì đâu kà :D) nhưng nén thất thóat được sử dụng rất nhiều xung quanh ta, nhất là trong lĩnh vực media như mp3, video, hình ảnh.
Với mp3 ta có thể nén thất thoát nó bằng cách giảm bitrate của nó xuống 192, 128, 64 hoặc 32 kbps, chất lượng có thể giảm nhưng tai người khó có thể phân biệt được khi dùng thiết bị âm thanh phổ thông.
Với video nén thất thóat có thể làm giảm độ phân giải (width, height), chất lượng hình ảnh, âm thanh của video.
Với hình ảnh ta có thể nén JPG, JPEG … để giảm kích thướt, chất lượng màu, độ nét từ ảnh gốc.

Gzip là một trong những chuẩn nén sử dụng thuật toán nén bảo tồn (lossless compression), có tên là Deflate, đây là thuật toàn kết hợp giữa thuật toán LZ77 (được Abraham Lempel và Jacob Ziv tìm ra năm 1977) và Huffman coding.
LZ77, xuất phát từ ý tưởng: dựa trên việc thay thế 1 cụm kí tự bằng một con trỏ, trỏ đến vị trí xuất hiện trước đó của cụm kí tự.
Huffman coding, dựa vào mô hình thống kê, tính tần suất xuất hiện của các ký tự, rồi gán cho các ký tự có tần suất cao một từ mã ngắn, các ký tự tần suất thấp từ mã dài. Phương pháp này phải lưu giữ lại bảng mã gắn kèm cùng với dữ liệu nén.

Gzip và AIR:

Ngày nay gzip được sử dụng rất nhiều, đặc biệt là một tính năng tăng tốc độ trao đổi dữ liệu được config trên server, để nén dữ liệu trả về client giúp cho việc truy cập được thực hiện nhanh chóng.

Một cách thông thường để giảm kích thước của dữ liệu trả về trên HTTP là cho phép máy chủ sử dụng gzip. Khi một request được gởi đi từ  một ứng dụng Flash Flex trên web browser, thì chính  browser này mới uncompresses dữ liệu, sau đó mới chuyển giao cho flash player.  Chính vì vậy mà với code actionscript 2 có trường hợp Flash Player trên firefox hiểu được gzip response, nhưng 1 số flash player trên browser khác thì không hiểu được (do cơ chế truyền dữ liệu gzip giữa browser và flash player). Đây cũng từng là một bug ID trên bug tracker của Adobe  http://bugs.adobe.com/jira/browse/FP-330

Đối với actionscript 3, Flash/Flex developer không cần phải lo lắng về việc nén hay giải nén gzip, tất cả đều được server và browser làm hết, flash player sẽ nhận được kết quả sau cùng đã giải nén.

Tuy nhiên, khi viết một ứng dụng trong AIR, không có sự giúp sức của trình duyệt để giải nén gzip và AIR 1,0 không có built-in tính năng giải nén gzip này.

Để giải quyết điều này ta buộc lòng phải giải nén gzip response bằng thuật giải Deflate như đã nói ở trên. (Hy vọng Adobe sẽ thêm tính năng này trong version AIR 2, nếu ko may tính năng này vẫn chưa có, thì đối với các ứng dụng di động ta cũng phải tự làm việc giải mã gzip )

Để lấy được dữ liệu nén trong HTTP response của server, trước tiên ta phải loại bỏ các header.
Để loại bỏ các header trong HTTP response ta sẽ sử dụng một thư viện nguồn mở của Paul Robertson: http://code.google.com/p/ascompress/ và giải nén gzip theo giải thuật Deflate (actionscript 3 có hỗ trợ sẵn) ByteArray.uncompress(CompressionAlgorithm.DEFLATE); (xem step 3)

Step 1: import thư viện của Robertson


import com.probertson.utils.GZIPEncoder;
import com.probertson.utils.GZIPFile;

Step 2: Lấy dữ liệu nén từ server (lưu ý phải lấy dữ liệu theo dạng binary)

var request:URLRequest = new URLRequest();
request.url = "YOUR_URL_SERVICE";
request.method = URLRequestMethod.POST;
request.contentType = "text/xml; charset=utf-8";
request.requestHeaders.push(new URLRequestHeader("Accept-Encoding", "gzip"));

var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, completeLoadHandler, false, 0, true);
loader.load(request);

Step 3: Bắt sự kiện load dữ liệu thành công

private function completeLoadHandler(event:Event) {
var data:ByteArray = URLLoader(event.target).data as ByteArray;
. . . .

Step 4: Loại bỏ các header chỉ lấy dữ liệu nén trong cục binary mới nhận đc :p

var encoderGzip:GZIPEncoder = new GZIPEncoder();
var gzipData:GZIPFile = encoderGzip.parseGZIPData(data);

Step 5: Giải nén lấy dữ liệu dạng xml cần thiết.

var uncompressedData:ByteArray = gzipData.getCompressedData();
uncompressedData.uncompress(CompressionAlgorithm.DEFLATE);
var dataXML:XML = new XML(uncompressedData.toString());

Ngoài ra khi chúng ta muốn viết một chương trình nén và giải nén file theo chuẩn Gzip bằng AIR, chúng ta cũng có thể dùng thư viện của Robertson http://probertson.com/projects/gzipencoder/

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: