אירועים שנשלחו על ידי שרתים (SSE) ב- JAX-RS

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

אירועים שנשלחו על ידי שרתים (SSE) הוא מפרט מבוסס HTTP המספק דרך ליצור חיבור ארוך-טווח וחד-ערוצי מהשרת ללקוח.

הלקוח יוזם את חיבור ה- SSE באמצעות סוג המדיה טקסט / זרם אירועים בתוך ה לְקַבֵּל כּוֹתֶרֶת.

מאוחר יותר, הוא מתעדכן אוטומטית מבלי לבקש מהשרת.

אנו יכולים לבדוק פרטים נוספים על המפרט במפרט הרשמי.

במדריך זה נציג את הטמעת ה- JAX-RS 2.1 החדשה של SSE.

לפיכך, נבדוק כיצד אנו יכולים לפרסם אירועים באמצעות ממשק ה- API של שרת JAX-RS. כמו כן, נבדוק כיצד נוכל לצרוך אותם באמצעות ממשק ה- API של JAX-RS או רק על ידי לקוח HTTP כמו ה- סִלְסוּל כְּלִי.

2. הבנת אירועי SSE

אירוע SSE הוא גוש טקסט המורכב מהשדות הבאים:

  • מִקרֶה: סוג האירוע. השרת יכול לשלוח הודעות רבות מסוגים שונים והלקוח יכול להקשיב רק לסוג מסוים או יכול לעבד אחרת כל סוג אירוע
  • נתונים: ההודעה שנשלחה על ידי השרת. יכולים להיות לנו קווי נתונים רבים לאותו אירוע
  • תְעוּדַת זֶהוּת: מזהה האירוע, המשמש לשליחת ה- מזהה אירוע אחרון כותרת, לאחר חיבור מחדש. זה שימושי מכיוון שהוא יכול למנוע מהשרת לשלוח אירועים שכבר נשלחו
  • נסה שוב: הזמן, באלפיות השנייה, ללקוח ליצור חיבור חדש כאשר הזרם אבד. המזהה שהתקבל לאחרונה יישלח אוטומטית דרך ה- מזהה אירוע אחרון כּוֹתֶרֶת
  • :': זו תגובה והיא מתעלמת מהלקוח

כמו כן, שני אירועים רצופים מופרדים על ידי קו כפול חדש '\ n \ n‘.

בנוסף, ניתן לכתוב את הנתונים באותו אירוע בשורות רבות כפי שניתן לראות בדוגמה הבאה:

אירוע: מזהה מלאי: 1: שינוי מחיר שוב: 4000 נתונים: {"dateTime": "2018-07-14T18: 06: 00.285", "id": 1, נתונים: "name": "GOOG", "price" : 75.7119} אירוע: מזהה מלאי: 2: שינוי מחיר מחיר שוב: 4000 נתונים: {"dateTime": "2018-07-14T18: 06: 00.285", "id": 2, "name": "IBM", "price ": 83.4611}

ב JAX RS, אירוע SSE מופשט על ידי ה- SseEvent מִמְשָׁק, או ליתר דיוק, על ידי שני ממשקי המשנה OutboundSseEvent ו InboundSseEvent.

בזמן ש OutboundSseEvent משמש ב- API של השרת ומעצב אירוע שנשלח, ה- InboundSseEvent משמש את ה- API של הלקוח וממצה אירוע שהתקבל.

3. פרסום אירועי SSE

עכשיו כשדנו מהו אירוע SSE בואו נראה כיצד נוכל לבנות ולשלוח אותו ללקוח HTTP.

3.1. הגדרת פרויקט

כבר יש לנו הדרכה בנושא הקמת פרויקט Maven מבוסס JAX RS. אל תהסס להסתכל שם כדי לראות כיצד להגדיר תלות ולהתחיל עם JAX RS.

3.2. שיטת משאבים SSE

שיטת SSE Resource היא שיטת JAX RS ש:

  • יכול לייצר a טקסט / זרם אירועים סוג המדיה
  • יש מוזרק SseEventSink פרמטר, לאן נשלחים אירועים
  • יכול להיות גם מוזרק ס.ס. פרמטר המשמש כנקודת כניסה ליצירת בונה אירועים
@GET @Path ("מחירים") @Produces ("זרם טקסט / אירוע") חלל ציבורי getStockPrices (@Context SseEventSink sseEventSink, @Context Sse sse) {// ...}

כתוצאה מכך, הלקוח צריך להגיש את בקשת ה- HTTP הראשונה, עם כותרת ה- HTTP הבאה:

קבל: טקסט / זרם אירוע 

3.3. מופע ה- SSE

מופע SSE הוא שעועית הקשר ש- JAX RS Runtime יעמיד להזרקה.

נוכל להשתמש בו כמפעל ליצירת:

  • OutboundSseEvent.Builder - מאפשר לנו ליצור אירועים אז
  • SseBroadcaster - מאפשר לנו לשדר אירועים למספר מנויים

בואו נראה איך זה עובד:

@Context בטל פומבי setSse (Sse sse) {this.sse = sse; this.eventBuilder = sse.newEventBuilder (); this.sseBroadcaster = sse.newBroadcaster (); }

עכשיו, בואו נתמקד בבונה האירועים. OutboundSseEvent.Builder אחראי על יצירת ה- OutboundSseEvent:

OutboundSseEvent sseEvent = this.eventBuilder .name ("stock") .id (String.valueOf (lastEventId)) .mediaType (MediaType.APPLICATION_JSON_TYPE) .data (Stock.class, stock). ConnectDelay (4000). תגובה ("שינוי מחיר) ") .build ();

כמו שאנו יכולים לראות, לבונה יש שיטות להגדיר ערכים לכל שדות האירועים המוצגים לעיל. בנוסף, ה- סוג המדיה() השיטה משמשת לסידור אובייקט Java של שדה הנתונים לפורמט טקסט מתאים.

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

אחרת, אם אנו רוצים לטפל באובייקט מותאם אישית, עלינו לציין את סוג המדיה או לספק מותאם אישית MessageBodyWriter.ה- Runtime של JAX RS מספק MessageBodyWriters עבור סוגי המדיה הידועים ביותר.

למופע Sse יש גם שני קיצורי דרך של בנאים ליצירת אירוע רק בשדה הנתונים, או בשדות הסוג והנתונים:

OutboundSseEvent sseEvent = sse.newEvent ("אירוע מגניב"); OutboundSseEvent sseEvent = sse.newEvent ("אירוע שהוקלד", "אירוע נתונים");

3.4. שולח אירוע פשוט

עכשיו כשאנחנו יודעים לבנות אירועים ואנחנו מבינים איך עובד SSE Resource. בואו נשלח אירוע פשוט.

ה SseEventSink ממשק מופשט חיבור HTTP יחיד. זמן הריצה של JAX-RS יכול להפוך אותו לזמין רק באמצעות הזרקה בשיטת המשאבים SSE.

שליחת אירוע היא אז פשוטה כמו הפעלת SseEventSink.לִשְׁלוֹחַ().

בדוגמה הבאה ישלח חבורה של עדכוני מניות ובסופו של דבר יסגור את זרם האירוע:

@GET @Path ("מחירים") @Produces ("זרם טקסט / אירוע") בטל פומבי getStockPrices (@Context SseEventSink sseEventSink /*..*/) {int lastEventId = // ..; תוך כדי (ריצה) {Stock stock = stockService.getNextTransaction (lastEventId); if (stock! = null) {OutboundSseEvent sseEvent = this.eventBuilder .name ("stock") .id (String.valueOf (lastEventId)) .mediaType (MediaType.APPLICATION_JSON_TYPE) .data (Stock.class, stock) .reconnectDelay ( 3000). Comment ("שינוי מחיר") .build (); sseEventSink.send (sseEvent); lastEventId ++; } // ..} sseEventSink.close (); }

לאחר שליחת כל האירועים, השרת סוגר את החיבור באמצעות קריאה מפורשת ל- סגור() שיטה או, רצוי, באמצעות נסה עם המשאב, כמו SseEventSink מרחיב את ניתן לסגירה אוטומטית מִמְשָׁק:

נסה (SseEventSink sink = sseEventSink) {OutboundSseEvent sseEvent = // .. sink.send (sseEvent); }

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

//localhost:9080/sse-jaxrs-server/sse.html

3.5. אירועי שידור

שידור הוא התהליך שבו אירועים נשלחים למספר לקוחות בו זמנית. זה מושג על ידי SseBroadcaster API, וזה נעשה בשלושה שלבים פשוטים:

ראשית, אנו יוצרים את SseBroadcaster אובייקט מהקשר Sse שהוזרק כפי שמוצג קודם:

SseBroadcaster sseBroadcaster = sse.newBroadcaster ();

לאחר מכן, על הלקוחות להירשם כדי לקבל את אירועי Sse. זה נעשה בדרך כלל בשיטת משאבים SSE שבה SseEventSink מוזרק מקרה ההקשר:

@GET @Path ("הירשם") @Produces (MediaType.SERVER_SENT_EVENTS) האזנה פומבית (@Context SseEventSink sseEventSink) {this.sseBroadcaster.register (sseEventSink); }

ולבסוף, אנו יכולים להפעיל את פרסום האירוע על ידי הפעלת מִשׁדָר() שיטה:

@GET @Path ("פרסם") שידור חלל ציבורי () {OutboundSseEvent sseEvent = // ...; this.sseBroadcaster.broadcast (sseEvent); }

זה ישלח את אותו אירוע לכל רשום SseEventSink.

כדי להציג את השידור אנו יכולים לגשת לכתובת אתר זו:

//localhost:9080/sse-jaxrs-server/sse-broadcast.html

ואז נוכל להפעיל את השידור על ידי הפעלת שיטת המשאבים broadcast ():

תלתל -X GET // localhost: 9080 / sse-jaxrs-server / sse / stock / publish

4. צריכת אירועי SSE

כדי לצרוך אירוע SSE שנשלח על ידי השרת, אנו יכולים להשתמש בכל לקוח HTTP, אך לצורך הדרכה זו נשתמש ב- API של לקוח JAX RS.

4.1. ממשק API לקוח JAX RS עבור SSE

כדי להתחיל עם ה- API של הלקוח עבור SSE, עלינו לספק תלות ליישום JAX RS Client.

כאן נשתמש ביישום לקוח Apache CXF:

 org.apache.cxf cxf-rt-rs-client $ {cxf-version} org.apache.cxf cxf-rt-rs-sse $ {cxf-version} 

ה SseEventSource הוא הלב של ה- API הזה, והוא בנוי מ- The WebTarget.

אנו מתחילים בהאזנה לאירועים נכנסים אשר מופשטים על ידי ה- InboundSseEvent מִמְשָׁק:

לקוח לקוח = ClientBuilder.newClient (); יעד מטרה אינטרנט = client.target (url); נסה (מקור SseEventSource = SseEventSource.target (target) .build ()) {source.register ((inboundSseEvent) -> System.out.println (inboundSseEvent)); source.open (); }

לאחר יצירת החיבור, יופעל צרכן האירוע הרשום עבור כל אחד מהם שהתקבל InboundSseEvent.

נוכל להשתמש ב- readData () שיטה לקריאת הנתונים המקוריים חוּט:

נתוני מחרוזת = inboundSseEvent.readData ();

לחלופין, אנו יכולים להשתמש בגרסה העמוסה כדי להשיג את אובייקט ה- Java הדה-מוריש באמצעות סוג המדיה המתאים:

מלאי מלאי = inboundSseEvent.readData (Stock.class, MediaType.Application_Json);

הנה, רק סיפקנו צרכן אירועים פשוט שמדפיס את האירוע הנכנס במסוף.

5. מסקנה

במדריך זה התמקדנו כיצד להשתמש באירועים שנשלחו על ידי השרת ב- JAX RS 2.1. הבאנו דוגמה המציגה כיצד לשלוח אירועים ללקוח יחיד וכן כיצד לשדר אירועים ללקוחות מרובים.

לבסוף, צרכנו אירועים אלה באמצעות ממשק ה- API של לקוח JAX-RS.

כרגיל, ניתן למצוא את הקוד של הדרכה זו באתר Github.


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