1. WebSocket에 대한 간단한 소개
인터넷이 개발되면서 전통적인 HTTP 프로토콜은 웹 애플리케이션의 점점 더 복잡한 요구를 충족시키기가 어려웠습니다. 최근 몇 년 동안 HTML5의 탄생으로 WebSocket 프로토콜이 제안되었습니다. 브라우저와 서버 간의 전이중 통신을 인식하고 브라우저와 서버 간의 통신 기능을 확장하며 서버가 클라이언트에 데이터를 적극적으로 전송할 수 있습니다.
우리는 전통적인 HTTP 프로토콜이 상태가 없다는 것을 알고 있습니다. 각 요청은 클라이언트 (예 : 브라우저)가 시작해야합니다. 처리 후 서버는 응답 결과를 반환합니다. 서버가 클라이언트에 데이터를 적극적으로 전송하는 것은 어렵습니다. 이런 종류의 클라이언트는 활성 파티이고 서버는 수동적 파티입니다. 기존 웹 모델은 드문 정보가 변경되는 웹 애플리케이션에 덜 문제를 일으키지 만 인스턴트 커뮤니케이션, 실시간 데이터, 구독 푸시 등과 같은 기능을 갖춘 실시간 정보와 같은 실시간 정보와 관련된 웹 애플리케이션에 큰 불편 함을 불러 일으 킵니다. WebSocket 사양이 제안되기 전에, 개발자는 종종 실시간 함정을 구현하기 위해 종종 트레이드 오프 솔루션을 구현하기 전에 : 폴링 및 코트 기술을 구현합니다. 실제로 후자는 본질적으로 일종의 여론 조사이지만 개선되었습니다.
폴링은 실시간 웹 애플리케이션을 구현하기위한 가장 독창적 인 솔루션입니다. 폴링 기술을 사용하려면 고객이 정해진 시간 간격으로 서버에 요청을 주기적으로 보내야하며 새로운 데이터 변경이 있는지 자주 쿼리해야합니다. 분명히이 접근법은 너무 많은 불필요한 요청으로 이어질 수 있으며 트래픽 및 서버 리소스를 낭비합니다.
혜성 기술은 긴 폴링 및 스트리밍 기술로 나눌 수 있습니다. 긴 폴링은 위에서 언급 한 투표 기술을 향상시켜 쓸모없는 요청을 줄입니다. 특정 데이터에 대한 만료 시간을 설정하고 데이터가 만료 된 후에만 서버에 요청을 보냅니다. 이 메커니즘은 데이터 변경이 특히 빈번하지 않은 상황에 적합합니다. 스트리밍 기술은 일반적으로 숨겨진 창을 사용하여 서버와의 HTTP 긴 연결을 설정하는 클라이언트를 말합니다. 서버는 HTTP 긴 연결을 유지하기 위해 연결 상태를 지속적으로 업데이트합니다. 이러한 방식으로 서버는이 긴 연결을 통해 클라이언트에 데이터를 적극적으로 보낼 수 있습니다. 스트리밍 기술은 대규모 동시성 환경에서 서버의 성능을 테스트 할 수 있습니다.
두 기술 모두 요청-응답 모드를 기반으로하며 실제 의미에서 실시간 기술로 간주되지 않습니다. 각각의 요청 또는 응답은 동일한 헤더 정보에 대한 일정량의 트래픽을 낭비하며 개발 복잡성도 높습니다.
HTML5가 출시되면서 WebSocket은 실제로 웹의 실시간 통신을 실현하여 B/S 모드가 C/S 모드의 실시간 통신 기능을 갖습니다. WebSocket의 워크 플로우는 다음과 같습니다. 브라우저는 JavaScript를 통해 WebSocket 연결을 설정하기 위해 서버에 요청을 보냅니다. WebSocket 연결이 성공적으로 설정된 후 클라이언트와 서버는 TCP 연결을 통해 데이터를 전송할 수 있습니다. WebSocket 연결은 본질적으로 TCP 연결이므로 각 전송마다 반복적 인 헤더 데이터를 전달할 필요가 없으므로 데이터 전송 볼륨은 폴링 및 혜성 기술보다 훨씬 작습니다. 이 기사는 WebSocket 사양을 자세히 소개하지 않지만 주로 Java Web에서 WebSocket의 구현을 소개합니다.
Javaee 7은 WebSocket 사양을위한 JSR-356 : Java API를 만들었습니다. Tomcat, Nginx, Jetty 등과 같은 많은 웹 컨테이너가 WebSocket을 지원합니다. Tomcat은 7.0.27 이후 WebSocket을 지원하고 7.0.47 이후 JSR-356을 지원합니다. 다음 데모 코드는 TomCat7.0.47 이상에 배치되어야합니다.
클라이언트 (웹 홈페이지) 코드 :
< %@ page language = "java"pageencoding = "utf-8" %> <! doctype html> <html> <head> <title> java backend websocket의 tomcat 구현 </title> </head> <clic> 환영 <br/> <input id = "tept"type ""text "/> <버튼 inclick ="> 메시지 보내기 () onclick = "Cosewebsocket ()"> CloseWeetCocket Connection </button> <hr/> <div id = "message"> </div> </body> <script type = "text/javaScript"> var webSocket = null; // 현재 브라우저가 if ( 'wind } else {alert ( '현재 브라우저를 지원하지 않음 WebSocket'); } // 연결 오류에 대한 콜백 메소드 webSocket.onerRor = function () {setMessageInnerHtml ( "WebSocket Connection의 오류"); }; // 성공적인 연결을위한 콜백 메소드 webSocket.onOpen = function () {setMessageInnerhtml ( "WebSocket Connection Success"); } // 메시지를받는 콜백 메소드 webSocket.onMessage = function (event) {setMessageInnerHtml (event.data); } // 연결을 닫는 콜백 메소드 websocket.onClose = function () {setMessageInnerHtml ( "WebSocket Connection"); } // 창 닫기 이벤트를 듣습니다. 창이 닫히면 연결이 끊어지기 전에 창이 닫히는 것을 방지하기 위해 WebSocket 연결을 적극적으로 닫으면 서버 측에 예외가 발생합니다. window.onbeforeunload = function () {closewebsocket (); } // 웹 페이지 기능에 메시지 표시 SetMessageInnerHtml (innerHtml) {document.getElementById ( 'message'). innerHtml + = innerHtml + '<br/>'; } // WebSocket Connection Connection CloseWebSocket () {WebSocket.close (); } // 메시지 보내기 함수 송신 () {var message = document.getElementById ( 'text'). value; WebSocket.Send (메시지); } </script> </html> Java 웹 백엔드 코드
패키지 cn.com; import java.io.ioexception; import java.util.concurrent.copyonwritearrayset; import javax.websocket.*; import javax.websocket.server.serverendpoint;/*** @serverendpoint annotation입니다. 이 기능은 주로 현재 클래스를 WebSocket 서버 측로 정의하는 것입니다. * 주석 값은 터미널 액세스 URL 주소에 대한 사용자의 연결을 듣는 데 사용됩니다. 클라이언트는이 URL*을 통해 WebSocket 서버에 연결할 수 있습니다* 요청이 이루어질 때마다*/@serverendpoint ( "/websocket") public class websockettest {// 정적 변수는 현재 온라인 연결 수를 기록하는 데 사용됩니다. 스레드-안전하도록 설계되어야합니다. 개인 정적 int onlinecount = 0; // 동시 패키지의 스레드 안전 세트는 각 클라이언트의 해당 MyWebSocket 객체를 저장하는 데 사용됩니다. 서버가 단일 클라이언트와 통신한다는 사실을 알기 위해 MAP를 사용하여이를 저장할 수 있습니다. 여기서 키는 사용자 개인 정적 정적 복사상 WRITEARRAYSET <WebsocketStest> websocketSet = new CopyOnWriteArrayset <WebsocketStest> ()를 식별 할 수 있습니다. // 특정 클라이언트와의 연결 세션은 개인 세션 세션을 통해 클라이언트에 데이터를 보내야합니다. /*** 연결을 성공적으로 호출하는 방법* @param 세션 선택적 매개 변수. 세션은 클라이언트와의 연결 세션이며,이를 통해 클라이언트에게 데이터를 보내야합니다*/ @onopen public void onopen (세션 세션) {this.session = session; websocketset.add (this); // 세트에서 addOnlineeCount ()에 추가; // 1 개의 온라인 번호 system.out.println을 추가합니다 ( "가입 할 새로운 연결이 있습니다! 현재 온라인 사람의 수는" + getonlineecount ()); } / *** 폐쇄 통화를 연결하는 방법* / @onclose public void onclose () {websocketSet.remove (this); // set에서 subonlineecount ()를 삭제합니다. // 온라인 번호 시스템으로 온라인 번호를 삭제합니다. } / *** 클라이언트 메시지를받은 후 호출 된 메소드* @param 메시지 클라이언트가 보낸 메시지* @param 세션 선택적 매개 변수* / @onmessage public void onMessage (문자열 메시지, 세션 세션) {System.out.println ( "클라이언트의 메시지 :" + 메시지); // (websockettest 항목 : websocketSet) {try {item.sendmessage (메시지); } catch (ioexception e) {e.printstacktrace (); 계속하다; }}}} / ** * 오류가 발생할 때 호출 * @param 세션 * @param error * / @onerror public void onerror (세션 세션, 던질 가능한 오류) {system.out.println ( "오류가 발생"); error.printstacktrace (); } /***이 방법은 위의 방법과 다릅니다. 주석이 없으며 필요에 따라 추가 된 방법입니다. * @param 메시지 * @throws ioException */ public void sendMessage (문자열 메시지)는 ioException {this.session.getBasicRemote (). sendText (메시지); //this.session.getasyncremote().sendtext(message); } public static synchronized intonlineecount () {return onlinecount; } public static synchronized void addOnlinecount () {websockettest.onlinecount ++; } public static synchronized void subonlinecount () {websockettest.onlinecount-; }}두 브라우저를 열고 URL을 입력 한 후 직접 실행하십시오.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.