บทช่วยสอนต่อไปนี้เป็นระบบ CRM ของ บริษัท ที่ฉันเข้าร่วมในการพัฒนา บริษัท และจัดเรียงข้อมูลที่เกี่ยวข้องบางอย่าง มีฟังก์ชั่นการผลักดันข้อความมากมายในระบบและใช้เทคโนโลยี WebSocket ตัวแก้ไขต่อไปนี้รวบรวมและแชร์บนแพลตฟอร์ม Wulin Network สำหรับการอ้างอิงของคุณ
1. การพึ่งพา Maven
<Ependency> <sderctId> javax.servlet </groupId> <ratifactid> javax.servlet-api </artifactid> <persion> 3.1.0 </version> </derness> <การพึ่งพา> <roupid> com.fasterxml.jackson.core </Groupid> 0 </เวอร์ชัน> </การพึ่งพา> <การพึ่งพา> <roupId> com.fasterxml.jackson.core </groupId> <ratifactid> Jackson-Core </artifactid> <cersion> 2.3.0 </เวอร์ชัน> </การพึ่งพา> <predency> -Databind </artifactId> <cersion> 2.3.0 </เวอร์ชัน> </การพึ่งพา> <การพึ่งพา> <roupId> org.springframework </groupId> <ratifactid> Spring-Websocket </artifactid> <cersion> 4.0.1 release </version> </derctency> <การพึ่งพา> <roupId> org.springframework </groupId> <ratifactId> Spring-Messaging </artifactId> <version> 4.0.1.Release </Serve> </การพึ่งพา>
2. การกำหนดค่า Spring-Servlet
<? xml version = "1.0" encoding = "utf-8"?> <ถั่ว xmlns = "http://www.springframework.org/schema/beans" xmlns: บริบท = "http://www.springframework.org/schema/cont ext "xmlns: mvc =" http://www.springframework.org/schema/mvc "xmlns: tx =" http://www.springframework.org/schema/tx " xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: websocket = "http://www.springframework.org/schema/websocket" xsi: schemalocation = "http: http: .springframework.org/schema/beanshttp: //www.springframework.org/schema/beans/spring-beans-3.1.xsdhttp: //www.springframework.org/schema/context/spring -context-3.1.xsdhttp: //www.springframework.org/schema/mvchttp: //www.springframework.o rg/schema/mvc/spring-mvc-3.1.xsdhttp: //www.springframework.org/schema/txhttp: //www.spr ingframework.org/schema/tx/spring-tx-3.1.xsdhttp://www.springframework.org/schema/websocketthttp://www.springframework.org/schema/websocket/spring-webet.orget id = "webSocket"/> <webSocket: handlers> <webSocket: mapping path = "/websocket" handler = "websocket"/> <websocket: handshake-interceptors> <bean/> <websocket: handshake-interceptors>
ในหมู่พวกเขาเส้นทางที่สอดคล้องกับเส้นทางคือเส้นทางอินเตอร์เฟสที่ปรับผ่านโปรโตคอล WS ในส่วนก่อนหน้า
3. การใช้งาน handshakeinterceptor
แพ็คเกจ cn.bridgeli.websocket; นำเข้า cn.bridgeli.utils.usermanager นำเข้า cn.bridgeli.util.dateutil; นำเข้า cn.bridgeli.sharesession.userinfo; นำเข้า org.slf4j.loggerfactory; นำเข้า org.springframework.http.server.serverhttprequest; นำเข้า org.springframework.http.server.serverhttpresponse; org.springframework.web.context.request.servletrequestattributes; นำเข้า org.springframework.web.socket.websockethandler; นำเข้า org.springframework.web.socket.server.support.httpsession java.util.map;/*** @description: สร้างอินเทอร์เฟซจับมือ*@date: 16-3-3*/คลาสสาธารณะ handshakeinterceptor ขยาย httpsessionhandshakeinterceptor {ส่วนตัว logger logger @private @overridepubter คำขอ, การตอบสนอง serverhttpresponse, websockethandler wshandler, แผนที่ <สตริง, วัตถุ> แอตทริบิวต์) โยนข้อยกเว้น {logger.info ("ก่อนที่จะสร้าง handshake ... "); servletrequestattributes attrs = userManager.getSessionUser (attrs.getRequest ()); usersocketVo usersocketVo = ใหม่ usersocketVo (); สตริงอีเมล = "" ถ้า (null! = curruser) {อีเมล = curruser.getEmail ();} ถ้า (stringutils.isblank (อีเมล) วันที่ ());} usersocketVo.SetUserEmail (อีเมล); Attributes.put ("session_user", usersocketVo); return super.beforehandshake (คำขอ, การตอบสนอง, wshandler, แอตทริบิวต์);}@overridepublic เป็นโมฆะ fterhandshake (Serverhttprequest Request, Serverhttpresponse การตอบสนอง, websockethandler wshandler, ex) {logger.info ("หลังจากสร้าง handshake ... ")เพราะฉันไม่เข้าใจดีมากฉันจึงเก็บรหัสเดิมไว้ในระดับสูงสุด นี่คือการนำผู้ใช้เข้าสู่ระบบเข้าสู่ระบบจากการลงชื่อเข้าใช้ครั้งเดียวแปลงเป็นวัตถุ usersocketVo และใส่ไว้ในแผนที่ ลองมาดูคำจำกัดความของวัตถุ usersocketvo
4. คำจำกัดความของ usersocketvo
แพ็คเกจ cn.bridgeli.websocket; นำเข้า org.springframework.web.socket.websocketsession; นำเข้า java.util.date;/*** @description: เอนทิตีของผู้ใช้ซ็อกเก็ตการเชื่อมต่อ*@date: 16-3-7*/คลาสสาธารณะ // อีเมลของผู้ใช้อีเมลวันที่เชื่อมต่อเวลาส่วนตัว; // เวลาการเชื่อมต่อที่ประสบความสำเร็จวันที่ส่วนตัวก่อนเวลา; // เวลาร้องขอล่าสุดวันที่ส่วนตัว newrequesttime; // เวลาคำขอใหม่วันที่ส่วนตัวล่าสุด = วันที่ใหม่ (); // เวลาการส่งครั้งสุดท้ายของข้อความลบวันที่ส่วนตัว LastTaSkSEndTime = วันที่ใหม่ (); // เวลาส่งครั้งสุดท้ายของงานส่วนตัว websocketsession webSocketSession; // wssession ที่สอดคล้องกับผู้ใช้เฉพาะแคชหนึ่งโดยค่าเริ่มต้น // getxx และ setxx}
สิ่งที่สำคัญที่สุดคือคุณสมบัติ WebSocketSession ซึ่งเราจะใช้ในภายหลัง
5. การใช้งาน websocketendpoint
แพ็คเกจ cn.bridgeli.websocket; นำเข้า org.slf4j.logger; นำเข้า org.slf4j.loggerfactory; นำเข้า org.springframework.beans.factory.annotation.autowired; นำเข้า org.springframework.web.socket org.springframework.web.socket.textmessage; นำเข้า org.springframework.web.socket.websocketsession; นำเข้า org.springframework.web.socket.handler.textwebsockethandler;/*** @description TextWebSocketHandler {ส่วนตัว logger สุดท้ายคงที่ logger = loggerFactory.getLogger (webSocketendpoint.class);@autoWiredPrivate NewsListenerImpl NewsListener; @OverrideProtected Void HandleTextMessage TextMessage (message.getPayload ()+"ได้รับที่เซิร์ฟเวอร์"); session.sendMessage (returnMessage);}/*** @description: หลังจากสร้างการเชื่อมต่อ* @param เซสชัน* @throws Exception*/ @uperridepublic Void (usersocketVo) เซสชัน. getattributes (). รับ ("session_user"); if (null! = usersocketVo) {usersocketVo.SetWebSocketSession (เซสชัน); if (wssessionlocalcache.exists (usersocketVo.getUserEmail ())) {wssessionLocalcache.remove (usersocketVo.getUserEmail ()); usersocketVo); newsListener.AfterConnectedEstablished (usersocketVo.getUserEmail ());} logger.info ("ซ็อกเก็ตประสบความสำเร็จในการสร้างการเชื่อมต่อ ... "); (usersocketVo) เซสชัน. getAttributes (). รับ ("session_user"); ถ้า (null! = usersocketVo) {wssessionLocalcache.remove (usersocketvo.getUseremail ();} logger.info6. การใช้งาน WSSessionLocalcache
แพ็คเกจ cn.bridgeli.websocket; นำเข้า java.io.serializable; นำเข้า java.util.arraylist; นำเข้า java.util.hashmap; นำเข้า java.util.list; นำเข้า java.util.map;/*** @description serializable {แผนที่คงที่ส่วนตัว <สตริง usersocketVo> wsSessionCache = ใหม่ hashmap <> (); บูลีนคงที่สาธารณะมีอยู่ (สตริง useremail) {ถ้า (! wssessioncache.containskey (useremail)) {return false; usersocketVo) {WSSessionCache.put (UserEmail, userEmail, userOctOctVo);} สาธารณะคงที่ผู้ใช้งานสแตติก public usersocketvo รับ (สตริง useremail) {return wssessioncache.get (useremail);} void remove (useremail) arrayList <> (wssessioncache.values ());}}หลังจากดูการดำเนินการแล้วเอฟเฟกต์ก็ชัดเจนยิ่งขึ้น มันเก็บข้อมูลล่าสุดของแต่ละ usersocketVo ในความเป็นจริงการใช้งาน WebSocket ของเราได้รับการคำนวณที่นี่ แต่ยังมีคลาสหลัก (คลาสของ Charlie เกี่ยวกับตรรกะทางธุรกิจ) ที่ยังไม่ได้ใช้งาน ในบทความถัดไปตัวอย่างแอปพลิเคชัน WebSocket Integrated Spring (ตอนที่ 2) เราจะเห็นวิธีการใช้คลาสนี้
รู้เบื้องต้นเกี่ยวกับ WebSocket Protocol
โปรโตคอล WebSocket เป็นฟังก์ชั่นที่สำคัญในฟิลด์เว็บที่กำหนดโดยข้อกำหนด RFC-6455: Full Duplex นั่นคือการสื่อสารสองทางระหว่างไคลเอนต์และเซิร์ฟเวอร์ มันเป็นคุณสมบัติที่น่าตื่นเต้น อุตสาหกรรมได้สำรวจสาขานี้มาเป็นเวลานาน เทคโนโลยีที่ใช้ ได้แก่ Java Applet, XMLHTTPREQUEST, Adobe Flash, ActiveXObject, เทคโนโลยีดาวหางต่างๆ, เหตุการณ์การส่งฝั่งเซิร์ฟเวอร์ ฯลฯ
ควรเข้าใจว่าก่อนที่จะใช้โปรโตคอล WebSocket คุณต้องใช้โปรโตคอล HTTP เพื่อสร้างการจับมือกันครั้งแรก สิ่งนี้ขึ้นอยู่กับกลไก - การสร้าง HTTP และขออัพเกรดโปรโตคอล (หรือการแปลงโปรโตคอล) เมื่อเซิร์ฟเวอร์เห็นด้วยมันจะตอบสนองต่อรหัสสถานะ HTTP 101 ซึ่งระบุว่าตกลงที่จะเปลี่ยนโปรโตคอล สมมติว่าการจับมือที่ประสบความสำเร็จผ่านซ็อกเก็ต TCP และคำขออัพเกรดโปรโตคอล HTTP จะถูกส่งผ่านจากนั้นทั้งไคลเอนต์และเซิร์ฟเวอร์สามารถส่งข้อความถึงกันและกันได้
Spring Framework 4.0 ขึ้นไปแนะนำโมดูลใหม่คือโมดูล Spring-Websocket ให้การสนับสนุนสำหรับการสื่อสาร WebSocket มันเข้ากันได้กับข้อกำหนดของ Java WebSocket API JSR-356 ในขณะที่ให้ฟังก์ชั่นเพิ่มเติม
คุณควรใช้ WebSocket ในสถานการณ์ใดบ้าง
ในเว็บแอปพลิเคชันเมื่อไคลเอนต์และเซิร์ฟเวอร์จำเป็นต้องแลกเปลี่ยนกิจกรรมด้วยความถี่ที่สูงขึ้นและเวลาแฝงที่ต่ำกว่าก็เหมาะสำหรับ WebSocket ดังนั้น WebSocket จึงเหมาะสำหรับสถานการณ์แอปพลิเคชันเช่นการเงินการเล่นเกมและการทำงานร่วมกัน
มันอาจไม่เหมาะสำหรับสถานการณ์แอปพลิเคชันอื่น ๆ ตัวอย่างเช่นการสมัครสมาชิกข่าวต้องมีข่าวด่วนที่จะแสดงและมันก็โอเคที่จะใช้การสำรวจนานหลายนาทีและความล่าช้าที่นี่เป็นที่ยอมรับ
แม้ในแอปพลิเคชันที่จำเป็นต้องใช้เวลาแฝงต่ำหากจำนวนข้อความที่ส่งอยู่ต่ำมาก (เช่นความล้มเหลวของเครือข่ายการตรวจสอบ) ควรพิจารณาเทคโนโลยีการสำรวจระยะยาว
เฉพาะในสถานการณ์ที่มีเวลาแฝงต่ำและการสื่อสารข้อความความถี่สูงการเลือกโปรโตคอล WebSocket นั้นเหมาะสมมาก แม้ในสถานการณ์แอปพลิเคชันดังกล่าวยังเป็นไปได้ที่จะเลือกการสื่อสาร WebSocket หรือไม่? หรือเลือก REST HTTP Communication?
คำตอบคือมันจะขึ้นอยู่กับความต้องการของแอปพลิเคชัน อย่างไรก็ตามยังเป็นไปได้ที่จะใช้เทคโนโลยีทั้งสองนี้ในเวลาเดียวกันเพื่อนำข้อมูลที่จำเป็นต้องแลกเปลี่ยนเป็น WebSocket บ่อยครั้งและใช้ REST API เป็นเทคโนโลยีการใช้งานทางธุรกิจตามกระบวนการ นอกจากนี้เมื่อข้อมูลบางอย่างจำเป็นต้องออกอากาศไปยังลูกค้าหลายรายในการโทร REST API ก็สามารถนำไปใช้ได้ผ่านการเชื่อมต่อ WebSocket
Framework Spring ให้คำอธิบายประกอบ @Controller และคำอธิบายประกอบ @RestController ซึ่งทั้งสองอย่างนี้สามารถใช้สำหรับการประมวลผลคำขอ HTTP และการประมวลผลข้อความ WebSocket นอกจากนี้วิธีการประมวลผลคำขอสปริง MVC หรือวิธีการประมวลผลคำขอแอปพลิเคชันอื่น ๆ สามารถใช้โปรโตคอล WebSocket เพื่อออกอากาศข้อความไปยังลูกค้าที่สนใจทั้งหมดหรือผู้ใช้ที่ได้รับมอบหมาย