1. การแนะนำสั้น ๆ เกี่ยวกับ WebSocket
ด้วยการพัฒนาอินเทอร์เน็ตโปรโตคอล HTTP แบบดั้งเดิมนั้นยากที่จะตอบสนองความต้องการที่ซับซ้อนมากขึ้นของเว็บแอปพลิเคชัน ในช่วงไม่กี่ปีที่ผ่านมามีการเสนอโปรโตคอล Websocket Protocol มันตระหนักถึงการสื่อสารแบบฟูลเพล็กซ์ระหว่างเบราว์เซอร์และเซิร์ฟเวอร์ขยายฟังก์ชั่นการสื่อสารระหว่างเบราว์เซอร์และเซิร์ฟเวอร์และทำให้เซิร์ฟเวอร์สามารถส่งข้อมูลไปยังไคลเอนต์ได้อย่างแข็งขัน
เรารู้ว่าโปรโตคอล HTTP แบบดั้งเดิมนั้นไร้สัญชาติ แต่ละคำขอจะต้องเริ่มต้นโดยลูกค้า (เช่นเบราว์เซอร์) หลังจากการประมวลผลเซิร์ฟเวอร์จะส่งคืนผลการตอบกลับ เป็นเรื่องยากสำหรับเซิร์ฟเวอร์ที่จะส่งข้อมูลไปยังไคลเอนต์อย่างแข็งขัน ไคลเอนต์ประเภทนี้เป็นปาร์ตี้ที่ใช้งานอยู่และเซิร์ฟเวอร์เป็นปาร์ตี้แบบพาสซีฟ โมเดลเว็บแบบดั้งเดิมทำให้เกิดปัญหาน้อยลงสำหรับเว็บแอปพลิเคชันที่มีการเปลี่ยนแปลงข้อมูลไม่บ่อยนัก แต่มันนำความไม่สะดวกอย่างมากสำหรับเว็บแอปพลิเคชันที่เกี่ยวข้องกับข้อมูลเรียลไทม์เช่นแอปพลิเคชันที่มีฟังก์ชั่นเช่นการสื่อสารแบบทันทีข้อมูลแบบเรียลไทม์การสมัครสมาชิก ฯลฯ ก่อนที่จะมีการเสนอข้อกำหนด WebSocket ในความเป็นจริงหลังเป็นแบบสำรวจ แต่ได้รับการปรับปรุงแล้ว
การสำรวจเป็นโซลูชันดั้งเดิมที่สุดในการใช้งานเว็บแอปพลิเคชันแบบเรียลไทม์ เทคโนโลยีการสำรวจต้องการให้ลูกค้าส่งคำขอไปยังเซิร์ฟเวอร์เป็นระยะตามช่วงเวลาที่กำหนดและสอบถามบ่อยครั้งว่ามีการเปลี่ยนแปลงข้อมูลใหม่หรือไม่ เห็นได้ชัดว่าวิธีการนี้สามารถนำไปสู่คำขอที่ไม่จำเป็นมากเกินไปการสูญเสียการรับส่งข้อมูลและทรัพยากรเซิร์ฟเวอร์
เทคโนโลยีดาวหางสามารถแบ่งออกเป็นเทคโนโลยีการสำรวจและสตรีมมิ่งที่ยาวนาน การสำรวจระยะยาวช่วยปรับปรุงเทคโนโลยีการสำรวจที่กล่าวถึงข้างต้นลดการร้องขอที่ไร้ประโยชน์ มันกำหนดเวลาหมดอายุสำหรับข้อมูลบางอย่างและส่งคำขอไปยังเซิร์ฟเวอร์หลังจากข้อมูลหมดอายุเท่านั้น กลไกนี้เหมาะสำหรับสถานการณ์ที่การเปลี่ยนแปลงข้อมูลไม่บ่อยนัก เทคโนโลยีสตรีมมิ่งมักหมายถึงไคลเอนต์โดยใช้หน้าต่างที่ซ่อนอยู่เพื่อสร้างการเชื่อมต่อ HTTP ยาวกับเซิร์ฟเวอร์ เซิร์ฟเวอร์จะอัปเดตสถานะการเชื่อมต่ออย่างต่อเนื่องเพื่อให้การเชื่อมต่อ HTTP ยาวมีชีวิตอยู่ ด้วยวิธีนี้เซิร์ฟเวอร์สามารถส่งข้อมูลไปยังไคลเอนต์ผ่านการเชื่อมต่อที่ยาวนานนี้ เทคโนโลยีสตรีมมิ่งอาจทดสอบประสิทธิภาพของเซิร์ฟเวอร์ในสภาพแวดล้อมที่มีขนาดใหญ่พร้อมกัน
เทคโนโลยีทั้งสองขึ้นอยู่กับโหมดการตอบสนองการร้องขอและไม่ได้รับการพิจารณาว่าเป็นเทคโนโลยีแบบเรียลไทม์ในความหมายที่แท้จริง การร้องขอหรือการตอบสนองของเสียจากการรับส่งข้อมูลจำนวนหนึ่งในข้อมูลส่วนหัวเดียวกันและความซับซ้อนในการพัฒนาก็สูงเช่นกัน
ด้วยการเปิดตัว HTML5 Websocket ตระหนักถึงการสื่อสารแบบเรียลไทม์ของเว็บอย่างแท้จริงทำให้โหมด B/S มีความสามารถในการสื่อสารแบบเรียลไทม์ของโหมด C/S เวิร์กโฟลว์ของ WebSocket มีดังนี้: เบราว์เซอร์ส่งคำขอไปยังเซิร์ฟเวอร์เพื่อสร้างการเชื่อมต่อ WebSocket ผ่าน JavaScript หลังจากสร้างการเชื่อมต่อ WebSocket สำเร็จไคลเอนต์และเซิร์ฟเวอร์สามารถส่งข้อมูลผ่านการเชื่อมต่อ TCP เนื่องจากการเชื่อมต่อ WebSocket เป็นการเชื่อมต่อ TCP จึงไม่จำเป็นต้องใช้ข้อมูลส่วนหัวซ้ำ ๆ ที่จะดำเนินการกับการส่งแต่ละครั้งดังนั้นปริมาณการส่งข้อมูลของข้อมูลจึงมีขนาดเล็กกว่าการสำรวจและเทคโนโลยีดาวหางมาก บทความนี้ไม่ได้แนะนำข้อกำหนดของ WebSocket ในรายละเอียด แต่ส่วนใหญ่แนะนำการใช้งาน WebSocket ใน Java Web
Javaee 7 ได้สร้าง JSR-356: Java API สำหรับข้อมูลจำเพาะ WebSocket เว็บคอนเทนเนอร์หลายรายการเช่น Tomcat, Nginx, Jetty ฯลฯ สนับสนุน WebSocket Tomcat รองรับ WebSocket ตั้งแต่ 7.0.27 และ JSR-356 ตั้งแต่ 7.0.47 รหัสสาธิตต่อไปนี้จะต้องมีการปรับใช้กับ Tomcat7.0.47 หรือสูงกว่าเพื่อเรียกใช้
ไคลเอนต์ (เว็บเพจเว็บ) รหัส:
< %@ page language = "java" pageencoding = "utf-8" %> <! doctype html> <html> <head> <title> การใช้งาน Tomcat ของ Java Backend WebSocket </title> </head> onclick = "CloseWebSocket ()"> ปิดการเชื่อมต่อ WebSocket </pution> <hr/> <div id = "ข้อความ"> </div> </body> <script type = "text/javascript"> var webSocket = null; // ตัดสินว่าเบราว์เซอร์ปัจจุบันรองรับ websocket if ('websocket' ในหน้าต่าง) {websocket = ใหม่ websocket ("ws: //172.16.98.31: 8080/websocket/websocket"); } else {Alert ('เบราว์เซอร์ปัจจุบันไม่รองรับ websocket'); } // วิธีการโทรกลับสำหรับข้อผิดพลาดในการเชื่อมต่อ websocket.onerror = function () {setMessageInnerHtml ("ข้อผิดพลาดในการเชื่อมต่อ WebSocket"); - // วิธีการโทรกลับสำหรับการเชื่อมต่อที่ประสบความสำเร็จ websocket.onopen = function () {setMessageInnerHtml ("การเชื่อมต่อ WebSocket สำเร็จ"); } // วิธีการโทรกลับของการรับข้อความ webSocket.onMessage = ฟังก์ชั่น (เหตุการณ์) {setMessageInnerHtml (event.data); } // วิธีการโทรกลับของการเชื่อมต่อการเชื่อมต่อ webSocket.onclose = function () {setMessageInnerHtml ("การเชื่อมต่อ WebSocket ปิด"); } // ฟังเหตุการณ์การปิดหน้าต่าง เมื่อปิดหน้าต่างให้ปิดการเชื่อมต่อ WebSocket อย่างแข็งขันเพื่อป้องกันไม่ให้หน้าต่างปิดก่อนที่การเชื่อมต่อจะถูกตัดการเชื่อมต่อและฝั่งเซิร์ฟเวอร์จะทำการยกเว้น window.onbeforeunload = function () {closewebsocket (); } // แสดงข้อความบนเว็บเพจฟังก์ชั่น setMessageInnerHtml (innerhtml) {document.getElementById ('ข้อความ'). innerhtml + = innerhtml + '<br/>'; } // ปิดฟังก์ชั่นการเชื่อมต่อ WebSocket CloseWebSocket () {webSocket.close (); } // ส่งฟังก์ชันข้อความส่ง () {var message = document.getElementById ('ข้อความ') ค่า; websocket.send (ข้อความ); } </script> </html> รหัสแบ็กเอนด์เว็บ Java
แพ็คเกจ cn.com; นำเข้า java.io.ioexception; นำเข้า java.util.concurrent.copyonwritearrayset; นำเข้า javax.websocket.*; นำเข้า Javax.websocket.server.serverendpoint; ฟังก์ชั่นส่วนใหญ่จะกำหนดคลาสปัจจุบันเป็นฝั่งเซิร์ฟเวอร์ WebSocket * ค่าคำอธิบายประกอบจะถูกใช้เพื่อฟังการเชื่อมต่อของผู้ใช้กับที่อยู่ URL การเข้าถึงเทอร์มินัล ไคลเอนต์สามารถเชื่อมต่อกับฝั่งเซิร์ฟเวอร์ WebSocket ผ่าน URL นี้* ทุกครั้งที่มีการร้องขออินสแตนซ์จะถูกสร้างขึ้น*/@ServerEndPoint ("/WebSocket") คลาสสาธารณะ WebSocketTest {// ตัวแปรคงที่ใช้เพื่อบันทึกจำนวนการเชื่อมต่อออนไลน์ปัจจุบัน ควรได้รับการออกแบบให้มีความปลอดภัยด้าย INT onLinEcount ส่วนตัว = 0; // ชุดเธรดที่ปลอดภัยของแพ็คเกจพร้อมกันใช้เพื่อจัดเก็บวัตถุ mywebsocket ที่สอดคล้องกันของไคลเอนต์แต่ละตัว ในการตระหนักว่าเซิร์ฟเวอร์สื่อสารกับไคลเอนต์เดียวคุณสามารถใช้แผนที่เพื่อจัดเก็บโดยที่คีย์สามารถระบุตัวตนส่วนตัวของผู้ใช้ copyOnWriteArrayset <WebSocketTest> WebSocketSet = ใหม่ CopyOnWriteArRaySet <WebSocketTest> (); // เซสชันการเชื่อมต่อที่มีลูกค้าบางรายจำเป็นต้องส่งข้อมูลไปยังไคลเอนต์ผ่านเซสชันส่วนตัวไอที /*** เมธอดสำหรับการเรียกการสร้างการเชื่อมต่อสำเร็จ* @param พารามิเตอร์ทางเลือก เซสชันคือเซสชันการเชื่อมต่อกับไคลเอนต์และจำเป็นต้องส่งข้อมูลไปยังไคลเอนต์ผ่านมัน*/ @onopen โมฆะสาธารณะ onopen (เซสชันเซสชัน) {this.session = เซสชัน; websocketSet.add (นี่); // เพิ่มลงใน addonlinecount () ในชุด; // เพิ่ม 1 หมายเลขออนไลน์ System.out.println ("มีการเชื่อมต่อใหม่ที่จะเข้าร่วม! จำนวนคนออนไลน์ปัจจุบันคือ" + getOnlinEcount ()); } / *** วิธีการเชื่อมต่อการโทรปิด* / @onclose โมฆะสาธารณะ onClose () {webSocketSet.remove (นี่); // ลบ subonLinEcount () จากชุด; // ลบหมายเลขออนไลน์โดย 1 หมายเลขออนไลน์ System.out.println ("มีการเชื่อมต่อปิดอยู่! จำนวนคนออนไลน์ปัจจุบันคือ" + getOnlinEcount ()); } / *** เมธอดที่เรียกว่าหลังจากรับข้อความไคลเอนต์* @param ข้อความข้อความที่ส่งโดยไคลเอนต์* @param เซสชันพารามิเตอร์ตัวเลือก* / @OnMessage โมฆะสาธารณะ onMessage (ข้อความสตริงเซสชันเซสชัน) {System.out.println ("ข้อความจากไคลเอนต์:" + ข้อความ); // batch message สำหรับ (websockettest item: websocketSet) {ลอง {item.sendMessage (ข้อความ); } catch (ioexception e) {e.printstacktrace (); ดำเนินการต่อ; }}}} / ** * เรียกว่าเมื่อเกิดข้อผิดพลาด * @param เซสชัน * @param ข้อผิดพลาด * / @onerror โมฆะสาธารณะ onerror (เซสชันเซสชัน, ข้อผิดพลาดแบบโยนได้) {system.out.println ("เกิดข้อผิดพลาด"); Error.PrintStackTrace (); } /*** วิธีนี้แตกต่างจากวิธีการข้างต้น ไม่มีคำอธิบายประกอบเป็นวิธีที่เพิ่มตามความต้องการของคุณ * ข้อความ @param * @throws ioexception */ โมฆะสาธารณะ sendMessage (ข้อความสตริง) พ่น IOException {this.session.getBasicRemote (). sendText (ข้อความ); //this.session.getasyncremote().sendtext(message); } สาธารณะคงที่แบบคงที่ int getOnlineCount () {return onlinecount; } โมฆะแบบสแตติกแบบคงที่สาธารณะ addOnLineCount () {webSocketTest.onlinEcount ++; } โมฆะแบบสแตติกแบบคงที่สาธารณะ subonLineCount () {webSocketTest.onlinEcount--; -เปิดเบราว์เซอร์สองตัวป้อน URL และเรียกใช้โดยตรง
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น