אירועים שנשלחו על ידי השרת באביב

1. סקירה כללית

במדריך זה נראה כיצד נוכל ליישם APIים מבוססי שרתים שנשלחו על ידי אירועים עם Spring.

במילים פשוטות, Server-Sent-Events, או בקיצור SSE, הוא תקן HTTP המאפשר ליישום אינטרנט לטפל בזרם אירועים חד כיווני ולקבל עדכונים בכל פעם שהשרת פולט נתונים.

גרסת אביב 4.2 כבר תמכה בו, אך החל באביב 5, כעת יש לנו דרך אידיומטית ונוחה יותר להתמודד עם זה.

2. SSE עם קפיץ 5 Webflux

כדי להשיג זאת, אנו יכולים לעשות שימוש ביישומים כגון שֶׁטֶף הכיתה המסופקת על ידי כור הספרייה, או פוטנציאלית ServerSentEvent יֵשׁוּת, שנותן לנו שליטה על מטא הנתונים של האירועים.

2.1. הזרמת אירועים באמצעות שֶׁטֶף

שֶׁטֶף הוא ייצוג תגובתי של זרם אירועים - הוא מטופל באופן שונה על פי הבקשה שצוינה או סוג מדיה התגובה.

כדי ליצור נקודת קצה של הזרמת SSE, נצטרך לעקוב אחר מפרטי W3C ולתאר את סוג ה- MIME שלה כ- טקסט / זרם אירועים:

@GetMapping (path = "/ stream-flux", produce = MediaType.TEXT_EVENT_STREAM_VALUE) stream Flux streamFlux () {return Flux.interval (Duration.ofSeconds (1)) .map (רצף -> "שטף -" + LocalTime.now () .toString ()); }

ה הַפסָקָה שיטה יוצרת א שֶׁטֶף שנפלט ארוך ערכים באופן הדרגתי. ואז אנו ממפים את הערכים הללו לתפוקה הרצויה שלנו.

בואו נתחיל את היישום שלנו וננסה אותו על ידי גלישה בנקודת הקצה ואז.

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

2.2. שימוש ב- ServerSentEvent אֵלֵמֶנט

כעת נעטוף את התפוקה שלנו חוּט לתוך ServerSentSevent להתנגד, ולבחון את היתרונות שבכך:

שטף ציבורי @ GetMapping ("/ stream-sse") streamEvents () {return Flux.interval (Duration.ofSeconds (1)) .map (רצף -> ServerSentEvent. בונה (). id (String.valueOf (רצף)). event ("periodic-event") .data (" SSE - "+ LocalTime.now (). ToString ()) .build ()); }

כפי שאנו יכולים להעריך, יש כמה יתרונות בשימוש ב- ServerSentEvent יֵשׁוּת:

  1. אנו יכולים להתמודד עם מטא הנתונים של האירועים, שנזדקק להם בתרחיש אמיתי
  2. אנחנו יכולים להתעלם "טקסט / זרם אירועיםהצהרת סוג מדיה

במקרה זה, ציינו תְעוּדַת זֶהוּת, שם אירוע, ובעיקר, בפועל נתונים של האירוע.

כמו כן, היינו יכולים להוסיף א הערות תכונה, ו נסה שוב ערך, שיציין את זמן החיבור מחדש שיש להשתמש בו בניסיון לשלוח את האירוע.

2.3. צריכת האירועים שנשלחו באמצעות השרת באמצעות לקוח אינטרנט

עכשיו בואו נצרוך את זרם האירועים שלנו עם WebClient.:

חלל ציבורי consumeServerSentEvent () {WebClient client = WebClient.create ("// localhost: 8080 / sse-server"); ParameterizedTypeReference סוג = חדש ParameterizedTypeReference() {}; שֶׁטֶף eventStream = client.get () .uri ("/ stream-sse"). retrieve () .bodyToFlux (type); eventStream.subscribe (content -> logger.info ("Time: {} - event: name [{}], id [{}], content [{}]", LocalTime.now (), content.event (), content.id (), content.data ()), שגיאה -> logger.error ("שגיאה בקבלת SSE: {}", שגיאה), () -> logger.info ("הושלם !!!")); }

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

בדוגמה שלנו השתמשנו ב- להחזיר שיטה, שהיא דרך פשוטה וישרה להשיג את גוף התגובה.

שיטה זו זורקת אוטומטית א WebClientResponseException אם אנו מקבלים תגובה 4xx או 5xx אלא אם כן אנו מטפלים בתרחישים בהוספת onStatus הַצהָרָה.

מצד שני, היינו יכולים להשתמש ב- לְהַחלִיף שיטה, המספקת גישה ל- ClientResponse וגם לא מסמן שגיאות בתגובות כושלות.

עלינו לקחת בחשבון שנוכל לעקוף את ServerSentEvent עטיפה אם איננו זקוקים למטא נתונים של האירוע.

3. הזרמת SSE באביב MVC

כפי שאמרנו, מפרט ה- SSE נתמך מאז אביב 4.2, כאשר ה- SseEmitter הכיתה הוצגה.

במילים פשוטות נגדיר שירות ExecutorService, חוט שבו SseEmitter תעשה את עבודתה בדחיפת נתונים ותחזיר את מופע הפולט, תוך שמירה על חיבור פתוח באופן זה:

@GetMapping ("/ stream-sse-mvc") SseEmitter ציבורי streamSseMvc () {SseEmitter emitter = SseEmitter new (); ExecutorService sseMvcExecutor = Executors.newSingleThreadExecutor (); sseMvcExecutor.execute (() -> {נסה {עבור (int i = 0; נכון; i ++) {אירוע SseEventBuilder = SseEmitter.event () .data ("SSE MVC -" + LocalTime.now (). toString ()) .id (String.valueOf (i)) .name ("sse event - mvc"); emitter.send (event); Thread.sleep (1000);}} catch (Exception ex) {emitter.completeWithError (ex); }}); פולט חוזר; }

הקפד תמיד לבחור את הזכות שירות ExecutorService לתרחיש מקרה השימוש שלך.

אנו יכולים ללמוד עוד על SSE באביב MVC ולעיין בדוגמאות אחרות על ידי קריאת מדריך מעניין זה.

4. הבנת אירועים המועברים על ידי השרת

עכשיו, כשאנחנו יודעים ליישם נקודות קצה של SSE, בואו ננסה להעמיק מעט על ידי הבנת כמה מושגים בסיסיים.

SSE הוא מפרט שאומץ על ידי רוב הדפדפנים כדי לאפשר הזרמת אירועים באופן לא כיוון בכל עת.

'האירועים' הם רק זרם של נתוני טקסט מקודדים UTF-8 העוקבים אחר הפורמט שהוגדר על ידי המפרט.

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

הערות נתמכות גם כן.

המפרט אינו מגביל את פורמט מטען הנתונים בשום צורה שהיא; אנחנו יכולים להשתמש בפשטות חוּט או מבנה JSON או XML מורכב יותר.

נקודה אחרונה שעלינו לקחת בחשבון היא ההבדל בין שימוש בהזרמת SSE לבין WebSockets.

בזמן WebSockets מציעים תקשורת דו-צדדית (דו-כיוונית) בין השרת ללקוח, בעוד ש- SSE משתמש בתקשורת חד כיוונית.

גַם, WebSockets אינו פרוטוקול HTTP, ובניגוד ל- SSE, הוא אינו מציע סטנדרטים לטיפול בשגיאות.

5. מסקנה

לסיכום, במאמר זה למדנו את המושגים העיקריים של הזרמת SSE, שהוא ללא ספק משאב נהדר שיאפשר לנו ליצור מערכות מהדור הבא.

אנו נמצאים כעת במצב מצוין להבין מה קורה מתחת למכסה המנוע כשאנו משתמשים בפרוטוקול זה.

יתר על כן, השלמנו את התיאוריה בכמה דוגמאות פשוטות, אשר ניתן למצוא במאגר Github שלנו.


$config[zx-auto] not found$config[zx-overlay] not found