לפני הכל נקדים לומר שכל הקרדיט לפוסט זה מוקדש לשלום פלס המוכשר שכל הקוד שיוצג לפניכם הוא שלו…
    [שלום ביקש להדגיש שהקוד נכתב כ-Proof of concept (“הוכחת היתכנות”) בלבד!]

    Chunked Data- הינו שיטת העברת נתונים בצורת “זריקה”, כלומר שליחת הנתונים כל פעם חלק מהמידע.

    שימושי כאשר מעוניינים  להעביר מידע  גדול, ותוך כדי שהמידע עובר, אפשר להתחיל להציג מה שהגיע. במקום לחכות עד שהכל יגיע, ואז להציג את המידע. (כמובן מדובר על מידע שמיוצר בזמן אמת ,ולא מידע ששמור ב DB. כי אז פשוט אפשר לגשת ולבקש כל פעם כמות מסוימת מהמקום האחרון שנשלח..)

    לעיתים אנחנו פונים לבקש מידע שלוקח לו זמן עקב ריבוי נתונים או עקב  עבודה על הנתונים, בשביל זה אפשר להחזיר את הנתונים בשיטה של “זריקת המידע” כלומר הקליינט יתחיל לקבל את המידע בחתיכות, להציג את מה שהוא קיבל ולהמשיך עד לסיופם קבלת המידע.

    להסבר נציג את הדוגמה הבאה(ניתן להוריד כאן את הקוד המלא):

    ה- controller:

    Code Snippet
    1. public class HomeController : Controller
    2. {
    3.     // GET: Home
    4.     public ActionResult Index()
    5.     {
    6.         return View();
    7.     }
    8.  
    9.     public ActionResult IndexData()
    10.     {
    11.         string msg = “Hello world! Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum rutrum pulvinar commodo. Proin vitae posuere augue. Nam rutrum ex eu magna finibus, at faucibus leo mattis. Vestibulum rutrum dui non nisi venenatis interdum cursus sed magna. Vestibulum placerat magna magna, vel tempus ligula aliquet ac. Phasellus egestas efficitur nulla, non pretium lacus tristique vitae. Nam dignissim non erat ac faucibus. In hac habitasse platea dictumst. Aenean sollicitudin nisi dui, vel condimentum erat aliquet vitae. Nullam feugiat massa vitae tellus dictum venenatis. Morbi vel turpis sit amet est volutpat volutpat. Nulla sit amet ex id eros elementum semper a a ex. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;”;
    12.         for (int i = 0; i < msg.Count(); i++)
    13.         {
    14.             Thread.Sleep(100);
    15.             byte[] buffer = System.Text.Encoding.UTF8.GetBytes(msg.Skip(i).Take(1).ToArray());
    16.             HttpContext.Response.OutputStream.Write(buffer, 0, buffer.Length);
    17.             HttpContext.Response.Flush();
    18.         }
    19.         HttpContext.Response.Close();
    20.         return null;
    21.     }
    22. }

    ה-client:

    Code Snippet
    1. (function () {
    2.     ‘use strict’;
    3.  
    4.     angular
    5.         .module(‘chunkedApp’)
    6.         .controller(‘chunkedController’, controller);
    7.  
    8.     controller.$inject = [‘$scope’, ‘chunkedHttp’];
    9.  
    10.     function controller($scope, chunkedHttp) {
    11.       
    12.  
    13.         getData();
    14.  
    15.         function getData() {
    16.             chunkedHttp.get(“/home/indexData”, function (res) {
    17.                 $scope.chunkedData = res;
    18.             })
    19.         }
    20.     }
    21. })();
     
    Code Snippet
    1. (function () {
    2.     ‘use strict’;
    3.  
    4.     angular
    5.         .module(‘chunkedApp’)
    6.         .factory(‘chunkedHttp’, factory);
    7.  
    8.     factory.$inject = [‘$rootScope’];
    9.  
    10.     function factory($rootScope) {
    11.         var service = {
    12.             get: get
    13.         };
    14.  
    15.         return service;
    16.  
    17.         function get(url, callback) {
    18.             var xhr = new XMLHttpRequest();
    19.             xhr.open(“GET”, url, true);
    20.             xhr.onprogress = function () {
    21.                 callback(xhr.responseText);
    22.                 $rootScope.$apply();
    23.             }
    24.             xhr.send();
    25.         }
    26.     }
    27. })();

    כמו שאתם רואים יש פה 3 קטעי קוד. הראשון הוא השרת ,ושני האחרים זה הקליינט.

    הקטע האחרון הוא מימוש של ajax באמצעות האוביקט xhr . נכתב בצורה הזאת כדי שנוכל לגשת ל –onprogress שבפונקציה הזאת אנחנו מפעילים callback ששלחנו בעת פניה לפונקציה זאת.

    בקליינט אנחנו מפעילים בעת טעינת העמוד את פונקצית getData (שורה 13 ) שהיא פונה לפונקציה get (שורה 16) שנמצאת לנו ב-factory בשם chunkedHttp (קטע ג’ שורה 17) עם ה-url וה-callback.

    בפונקציה זו אנחנו פונים לשרת לפונקציה indexData .

    שורה 18- יצירת אוביקט מסוג XMLHttpRequest .

    שורה 19- פתיחת הקריאה עם הurl שקיבלנו.

    שורה 20-רישום לפונקציה שתופעל  onprogress.

    שורה 24-שליחה לשרת.

    בשרת מה שאנחנו עושים הוא בעצם ה-chunked Data אנחנו דואגים לשלוח את המידע בחתיכות .

    יצרנו string בשם msg ועברנו בלולאה עליו.

    שורה 14- עצרנו את הthread רק בשביל שיקח לנו זמן בין חלק לחלק. כי כמובן בדוגמה הנ”ל אין צורך באמת בשימוש בchunked כמו שאמרנו מדובר על מידע גדול וכו’..

    שורה 15- אנחנו לוקחים כל פעם אות אחת מ-msg וממירים אותה לbyte array כי בשביל לעבוד  עם chunked צריך לעבוד עם byte  כי זה הדרך להחזיר לקליינט את המידע…

    שורה 16-אנחנו כותבים ל- OutputStream מה שיש לנו כרגע ב buffer (שזה באצם האות שהומרה לbyte[]).

    שורה 17-HttpContext.Response.Flush מה שהוא עושה זה בעצם שולח את המידע לקליינט מה שיש לו כרגע ב-OutputStream (וזה ילך לפונקציה שמופעלת בקליינט ב-onprogress.)

    שורה 19- שורה זו תתבצע כמובן לאחר שתסתיים הלולאה מה שאומר שכל המידע עבר. שורה זאת סוגרת את הresponse מה שאומר לקליינט שאין לו יותר מה לגשת לשרת.

     

    מה שקורה זה שב-onprogress הקליינט יפעיל את הcallback שהוא קיבל והוא שולח לו את המידע שיש לו ב-xhr.responseText(חלק ג’ שורה 21) הפונקציה הזאת שמה בתוך המשתנהscope.chunkedData את ה-xhr.responseText . וככה המידע החלקי מוצג מה שמייעל את המערכת ונותן חווית משתמש טובה יותר…