1. การแนะนำสั้น ๆ เกี่ยวกับ WebSocket
WebSocket Protocol เป็นโปรโตคอลใหม่สำหรับ HTML5 ใช้การสื่อสารแบบฟูลดูเพล็กซ์ระหว่างเบราว์เซอร์และเซิร์ฟเวอร์ การจับมือกันครั้งแรกต้องการความช่วยเหลือจากคำขอ HTTP ในการจับมือกัน
ด้วยการพัฒนาอินเทอร์เน็ตโปรโตคอล HTTP แบบดั้งเดิมนั้นยากที่จะตอบสนองความต้องการที่ซับซ้อนมากขึ้นของเว็บแอปพลิเคชัน ในช่วงไม่กี่ปีที่ผ่านมามีการเสนอโปรโตคอล Websocket Protocol มันตระหนักถึงการสื่อสารแบบฟูลเพล็กซ์ระหว่างเบราว์เซอร์และเซิร์ฟเวอร์ขยายฟังก์ชั่นการสื่อสารระหว่างเบราว์เซอร์และเซิร์ฟเวอร์และทำให้เซิร์ฟเวอร์สามารถส่งข้อมูลไปยังไคลเอนต์ได้อย่างแข็งขัน
พื้นหลัง WebSocket
การสื่อสารทางเดียวเท่านั้นที่สามารถทำได้ผ่าน HTTP ในเบราว์เซอร์ ดาวหางสามารถจำลองการสื่อสารสองทางในระดับหนึ่ง แต่มีประสิทธิภาพต่ำและต้องการการสนับสนุนที่ดีจากเซิร์ฟเวอร์ ซ็อกเก็ตและ XMLSocket ในแฟลชสามารถตระหนักถึงการสื่อสารสองทางที่แท้จริงและฟังก์ชั่นทั้งสองนี้สามารถใช้ใน JavaScript ผ่าน Flex Ajax Bridge อาจเป็นไปได้ว่าหาก WebSocket ถูกนำไปใช้ในเบราว์เซอร์มันจะแทนที่เทคโนโลยีสองประการข้างต้นและใช้กันอย่างแพร่หลาย เมื่อเผชิญกับสถานการณ์นี้ HTML5 กำหนดโปรโตคอล WebSocket ซึ่งสามารถประหยัดทรัพยากรเซิร์ฟเวอร์และแบนด์วิดท์ได้ดีขึ้นและบรรลุการสื่อสารแบบเรียลไทม์
โปรโตคอล WebSocket ยังใช้ใน Javaee7
เรารู้ว่าโปรโตคอล 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 หรือสูงกว่าเพื่อเรียกใช้
2. ตัวอย่าง WebSocket
2.1. สร้างโครงการทดสอบ Javaweb ใหม่
เพิ่มการพึ่งพาแพ็คเกจ JAR ใน pom.xml
<Ederency> <sderctId> Javax </groupId> <ratifactId> Javaee-Api </artifactId> <version>. </version> <pope> ให้ </cope> </predency>
ไคลเอนต์ (เว็บเพจเว็บ) รหัส:
< %@ page language = "java" pageencoding = "utf-" %> <! doctype html> <html> <head> <title> การใช้งาน Tomcat ของ Java Backend Websocket </title> </head> <body> ยินดีต้อนรับ <brest) onclick = "CloseWebSocket ()"> ปิดการเชื่อมต่อ WebSocket </ปุ่ม> <hr/> <div id = "ข้อความ"> </div> </body> <script type = "text/javascript"> var webSocket = null; WebSocket ("ws: // localhost:/websocket");} else {แจ้งเตือน ('เบราว์เซอร์ปัจจุบันไม่รองรับ websocket')} // วิธีการโทรกลับสำหรับข้อผิดพลาดในการเชื่อมต่อ websocket.onerror = function () {setMessageinnerhtml ( {setMessageInnerHtml ("การเชื่อมต่อ websocket สำเร็จ");} // วิธีการโทรกลับสำหรับการรับข้อความ websocket.onmessage = ฟังก์ชั่น (เหตุการณ์) {setMessageInnerHtml (event.data);} // การเชื่อมต่อการเชื่อมต่อ websocket.onclose = function () เหตุการณ์. เมื่อปิดหน้าต่างให้ปิดการเชื่อมต่อ WebSocket อย่างแข็งขันเพื่อป้องกันไม่ให้หน้าต่างปิดก่อนที่การเชื่อมต่อจะถูกตัดการเชื่อมต่อและฝั่งเซิร์ฟเวอร์จะทำการยกเว้น window.onbeforeunload = function () {closewebsocket ();} // แสดงข้อความบนหน้าเว็บฟังก์ชัน setMessageInnerhtml (innerhtml) {document.getElementById ('ข้อความ'). innerhtml + = innerhtml + '<bbr/>';} // {webSocket.close ();} // ส่งฟังก์ชั่นข้อความส่ง () {var message = document.getElementById ('text'). value; websocket.send (ข้อความ);} </script> </html> รหัสแบ็กเอนด์เว็บ Java
แพ็คเกจ me.gacl.websocket; นำเข้า java.io.ioexception; นำเข้า java.util.concurrent.copyonwritearrayset; นำเข้า javax.websocket.*; นำเข้า Javax.websocket.server.serverendpoint;/*** ฟังก์ชั่นส่วนใหญ่จะกำหนดคลาสปัจจุบันเป็นฝั่งเซิร์ฟเวอร์ WebSocket ค่าของคำอธิบายประกอบจะถูกใช้เพื่อฟังการเชื่อมต่อของผู้ใช้กับที่อยู่ URL ของการเข้าถึงเทอร์มินัลของผู้ใช้ ไคลเอนต์สามารถเชื่อมต่อกับฝั่งเซิร์ฟเวอร์ WebSocket ผ่าน URL*/@ServerEndPoint ("/websocket") คลาสสาธารณะ WebSocketTest {// ตัวแปรคงที่ที่ใช้ในการบันทึกจำนวนการเชื่อมต่อออนไลน์ปัจจุบัน ควรได้รับการออกแบบให้มีความปลอดภัยด้าย INT onLineCount ส่วนตัวส่วนตัว =; // ชุดเธรดที่ปลอดภัยของแพ็คเกจพร้อมกันใช้เพื่อจัดเก็บวัตถุ mywebsocket ที่สอดคล้องกันของไคลเอนต์แต่ละตัว ในการตระหนักว่าเซิร์ฟเวอร์สื่อสารกับไคลเอนต์เดียวคุณสามารถใช้แผนที่เพื่อจัดเก็บโดยที่คีย์สามารถระบุ copyonWriteArraySet ของผู้ใช้ส่วนตัว <SopeocketTest> webSocketSet = ใหม่ CopyOnWriteArRayset <WebSocketTest> () // การเชื่อมต่อกับการเชื่อมต่อ เซสชันคือเซสชันการเชื่อมต่อที่มีลูกค้าบางรายและจำเป็นต้องส่งข้อมูลไปยังไคลเอนต์ผ่านมัน*/@onopenpublic เป็นโมฆะ Onopen (เซสชันเซสชัน) {this.session = เซสชัน; websocketSet.add (นี่); // เพิ่มลงใน addonlinecount () ในชุด; // เพิ่มลงใน System.out.println ("มีการเชื่อมต่อใหม่ที่จะเข้าร่วม! จำนวนปัจจุบันของคนออนไลน์คือ" + getOnlineCount ());}/*** วิธีการเชื่อมต่อการโทรปิด*/@onclosepublic onclose () {webSocketSet.Remove (นี่); // ลบ subonLinEcount () จากชุด; // การลดลงของหมายเลขออนไลน์ system.out.println ("มีการเชื่อมต่อปิดอยู่! จำนวนปัจจุบันของคนออนไลน์คือ" + getOnlinEcount ());}/*** วิธีการเรียกหลังจากรับข้อความไคลเอนต์* @param ข้อความข้อความที่ส่งโดยลูกค้า {paramed { @params sessions ข้อความ); // batch message สำหรับ (websocketTest item: webSocketSet) {ลอง {item.sendMessage (ข้อความ);} catch (ioexception e) {e.printstacktrace (); ดำเนินการต่อ;}}}/*** เรียกว่า ข้อผิดพลาด) {System.out.println ("เกิดข้อผิดพลาด"); Error.printStackTrace ();}/*** วิธีนี้แตกต่างจากวิธีการข้างต้น ไม่มีคำอธิบายประกอบเป็นวิธีที่เพิ่มตามความต้องการของคุณ * @param message* @throws ioexception*/โมฆะสาธารณะ sendmessage (ข้อความสตริง) พ่น ioexception {this.session.getBasicremote (). sendtext (ข้อความ); // this.session.getasyncremote () SendText (ข้อความ) addOnLinEcount () {webSocketTest.onlinEcount ++;} โมฆะแบบคงที่แบบคงที่สาธารณะ subonLineCount () {webSocketTest.onlinEcount--;}} 1.2. ผลการดำเนินงาน
เปิดเบราว์เซอร์ Google และเบราว์เซอร์ Firefox ในเวลาเดียวกันสำหรับการทดสอบการจำลองหลายลูกค้า เอฟเฟกต์การดำเนินการมีดังนี้:
เนื้อหาข้างต้นเป็นตัวอย่างการสอนสำหรับการใช้ WebSocket โดย Java Backend Tomcat แนะนำให้คุณรู้จัก ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน!