מבוא ל- WebSockets עם אביב

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

במאמר זה ניצור יישום אינטרנט פשוט המיישם הודעות באמצעות ה- יכולות WebSocket חדשות הוצג עם Spring Framework 4.0.

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

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

2. תלות Maven

מכיוון שמדובר בפרויקט מבוסס Maven, אנו מוסיפים תחילה את התלות הנדרשת ל- pom.xml:

 org.springframework spring-websocket 5.2.2.RELEASE org.springframework spring-messaging 5.2.2.RELEASE 

בנוסף, כפי שנשתמש ג'סון כדי לבנות את גוף המסרים שלנו, עלינו להוסיף את ג'קסון תלות. זה מאפשר לאביב להמיר את אובייקט הג'אווה שלנו מ / אל ג'סון:

 com.fasterxml.jackson.core jackson-core 2.10.2 com.fasterxml.jackson.core jackson-databind 2.10.2 

אם אתה רוצה לקבל את הגרסה החדשה ביותר של הספריות שלמעלה, חפש אותן ב- Maven Central.

3. הפעל את WebSocket באביב

הדבר הראשון לעשות הוא לאפשר את יכולות ה- WebSocket. לשם כך עלינו להוסיף תצורה ליישום שלנו ולהביא הערה למחלקה זו @EnableWebSocketMessageBroker.

כשמו כן הוא, הוא מאפשר טיפול בהודעות WebSocket, בגיבוי מתווך הודעות:

@Configuration @EnableWebSocketMessageBroker המחלקה הציבורית WebSocketConfig מרחיב את AbstractWebSocketMessageBrokerConfigurer {@ Override public void configureMessageBroker (MessageBrokerRegistry config) {config.enableSimpleBroker ("/ topic"); config.setApplicationDestinationPrefixes ("/ app"); } @Override public public register registerStompEndpoints (StompEndpointRegistry registry) {registry.addEndpoint ("/ chat"); registry.addEndpoint ("/ chat"). withSockJS (); }} 

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

נשלים את התצורה הפשוטה שלנו על ידי ייעוד הקידומת "/ app" לסינון יעדים הממוקדים לשיטות המויינות ליישום (באמצעות @MessageMapping).

ה registerStompEndpoints השיטה רושמת את נקודת הקצה "/ צ'אט", ומאפשרת תמיכת STOMP של אביב. זכור כי אנו מוסיפים כאן גם נקודת קצה שעובדת ללא SockJS למען האלסטיות.

נקודת קצה זו, כאשר היא מקודמת עם "/ app", היא נקודת הקצה ש- ChatController.send () השיטה ממופה לטיפול.

זה גם מאפשרת את אפשרויות ה- fallback של SockJS, כך שאפשר יהיה להשתמש באפשרויות העברת הודעות חלופיות אם WebSockets אינם זמינים. זה שימושי מכיוון ש- WebSocket אינו נתמך עדיין בכל הדפדפנים ועשוי להיות מונע על ידי פרוקסי רשת מגבילים.

החיסרונות מאפשרים ליישומים להשתמש ב- API של WebSocket אך מתפנים בחינניות לחלופות שאינן WebSocket בעת הצורך בזמן הריצה.

4. צור את מודל ההודעה

כעת, לאחר שהקמנו את הפרויקט והגדרנו את יכולות ה- WebSocket, עלינו ליצור הודעה לשליחה.

נקודת הקצה תקבל הודעות המכילות את שם השולח וטקסט בהודעת STOMP שגופה הוא ג'סון לְהִתְנַגֵד.

ההודעה עשויה להיראות כך:

{"from": "John", "text": "Hello!" } 

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

הודעה בכיתה ציבורית {פרטי מחרוזת מ; טקסט מחרוזת פרטי; // גטרים וקובעים} 

כברירת מחדל, אביב ישתמש ב- ג'קסון הספרייה להמרת אובייקט המודל שלנו ל- JSON וממנו.

5. צור בקר לטיפול בהודעות

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

הקשר בין נקודת הקצה לבקר נותן לנו את היכולת לטפל בהודעה במידת הצורך:

@MessageMapping ("/ צ'ט") @SendTo ("/ נושא / הודעות") OutputMessage לשלוח (הודעת הודעה) זורק חריג {זמן מחרוזת = חדש SimpleDateFormat ("HH: mm"). פורמט (תאריך חדש ()); להחזיר OutputMessage חדש (message.getFrom (), message.getText (), זמן); } 

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

לאחר הטיפול בהודעה שלנו, אנו שולחים אותה ליעד המתאים המוגדר באמצעות ה- @לשלוח ל ביאור. כל המנויים ל"/ נושא / הודעותהיעד יקבל את ההודעה.

6. צור לקוח דפדפן

לאחר ביצוע התצורות שלנו בצד השרת, נשתמש ב- ספריית לקוח sockjs לבניית דף HTML פשוט המתקשר עם מערכת המסרים שלנו.

קודם כל, עלינו לייבא את sockjs ו לִדרוֹך ספריות לקוח Javascript. בשלב הבא נוכל ליצור לְחַבֵּר() פונקציה לפתיחת התקשורת עם נקודת הסיום שלנו, א לשלוח הודעה() פונקציה לשליחת הודעת STOMP שלנו ו- לְנַתֵק() פונקציה לסגירת התקשורת:

  צ'אט WebSocket var stompClient = null; function setConnected (מחובר) {document.getElementById ('להתחבר'). מושבת = מחובר; document.getElementById ('ניתוק'). מושבת =! מחובר; document.getElementById ('שיחה דיב'). style.visibility = מחובר? 'גלוי': 'נסתר'; document.getElementById ('תגובה'). innerHTML = ''; } function connect () {var socket = new SockJS ('/ chat'); stompClient = Stomp.over (שקע); stompClient.connect ({}, function (frame) {setConnected (true); console.log ('Connected:' + frame); stompClient.subscribe ('/ נושא / הודעות', פונקציה (messageOutput) {showMessageOutput (JSON.parse) (messageOutput.body));});}); } לנתק פונקציה () {if (stompClient! = null) {stompClient.disconnect (); } setConnected (false); console.log ("מנותק"); } פונקציה sendMessage () {var from = document.getElementById ('מ-'). ערך; var text = document.getElementById ('טקסט'). ערך; stompClient.send ("/ app / chat", {}, JSON.stringify ({'from': from, 'text': text})); } פונקציה showMessageOutput (messageOutput) {var response = document.getElementById ('response'); var p = document.createElement ('p'); p.style.wordWrap = 'break-word'; p.appendChild (document.createTextNode (messageOutput.from + ":" + messageOutput.text + "(" + messageOutput.time + ")")); response.appendChild (p); }

התחבר ניתוק

לִשְׁלוֹחַ

7. בדיקת הדוגמא

כדי לבדוק את הדוגמה שלנו, אנו יכולים לפתוח כמה חלונות דפדפן ולגשת לדף הצ'אט בכתובת:

// localhost: 8080

לאחר שהדבר נעשה, אנו יכולים להצטרף לצ'אט על ידי הזנת כינוי ולחיצה על כפתור ההתחברות. אם נחבר ונשלח הודעה נוכל לראות אותה בכל הפעלות הדפדפן שהצטרפו לצ'אט.

התבונן בצילום המסך כדי לראות דוגמה:

8. מסקנה

במדריך זה בחנו את תמיכת WebSocket של Spring. ראינו את התצורה שלה בצד השרת ובנינו עמית פשוט בצד הלקוח בעזרת sockjs ו לִדרוֹך ספריות Javascript.

את קוד הדוגמה ניתן למצוא בפרויקט GitHub.


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