1. WebSocket 소개
주가, 온라인 채팅, 웨이보 등 높은 실시간 데이터가 필요한 일부 시스템의 경우 데이터는 실시간 푸시가 필수입니다. 실시간 푸시를 달성하는 일반적인 방법은 다음과 같습니다.
1. 폴링: 가끔씩 데이터를 보냅니다(예: webqq)
2. 소켓: 과거에는 일반 웹 페이지가 소켓을 지원하지 않았습니다 메시지를 받습니다. 플래시나 애플릿을 소켓 클라이언트로 사용할 수 있습니다
3. 긴 연결: TCP 연결 유지 기간 동안 데이터 패킷이 전송되지 않으면 TCP 연결에서 여러 데이터 패킷을 지속적으로 보낼 수 있음을 의미합니다. 이 연결을 유지하려면 양측 모두 탐지 패킷을 보내야 하며 일반적으로
온라인 유지 관리를 직접 수행해야 합니다.
------------------------------- --- ---------------------------------- ---
html5는 window.WebSocket(firefox의 window.MozWebSocket)을 통해 http가 아닌 양방향 연결을 제공합니다. 이 연결은 colse로 표시되지 않는 한 실시간이며 영구적입니다.
즉, 클라이언트가 소켓을 열고 연결을 요청하는 한(한 번만) 서버는 수동 감지 및 유지 관리 없이 실시간으로 메시지를 주고받을 수 있습니다. 상태.
WebSocket에서 제공하는 메소드와 속성은 firebug에 Window.WebSocket.prototype을 입력하면 확인할 수 있습니다.
다음 코드는 기본 사용법 아이디어를 나열합니다.
var location = "ws://localhost:port/serlet/xxx"; //服务端处理的servlet var webSocket = new WebSocket(location); //webSocket.readyState var readyStates = { "CONNECTING":"正在连接“, ”OPEN“ : "已建立连接", "CLOSING":"正在关闭连接", "CLOSED":"已关闭连接" } webSocket.send(data);//发送数据到服务端,目前只支持文本类型。JSON.stringify(data);JSON.parse(data); webSocket.onMessage = function(event){ var data = event.data;//从服务端过来的数据 } webSocket.onOpen = function(event){ //开始通信 } webSocket.onClose = function(event){ //结束通信 } webSocket.close();
2. jetty(java 서버) 기반 예제
현재 Apache는 WebSocket을 지원하지 않습니다. 다양한 언어에는 이를 구현하는 방법이 다르며 이는 Java로 구현됩니다.
1단계: jetty를 다운로드하고 압축을 풀고 디스크에 넣습니다. Jetty7 이상은 WebSocket만 지원합니다. 다운로드 주소: download.eclipse.org/jetty/stable-7/dist/
2단계: eclipse 다운로드 (MyEclipse는 권장되지 않습니다. 번거롭습니다. 다른 플러그인을 설치해야 하며 jetty7을 지원해야 합니다. 버전이 높을수록 좋습니다.
3단계: eclipse에 플러그인 설치, 도움말---새 소프트웨어 설치...----URL은 eclipse-jetty.sourceforge.net/update입니다. /
4단계: 새 동적 웹 프로젝트 생성
5단계: 다음 코드를 복사합니다. TailorWebSocketServlet.java
package com.test; import java.io.IOException; import java.util.Date; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.websocket.WebSocket; import org.eclipse.jetty.websocket.WebSocketServlet; public class TailorWebSocketServlet extends WebSocketServlet { private static final long serialVersionUID = -7289719281366784056L; public static String newLine = System.getProperty("line.separator"); private final Set<TailorSocket> _members = new CopyOnWriteArraySet<TailorSocket>(); private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); public void init() throws ServletException { super.init(); executor.scheduleAtFixedRate(new Runnable() { public void run() { System.out.println("Running Server Message Sending"); for(TailorSocket member : _members){ System.out.println("Trying to send to Member!"); if(member.isOpen()){ System.out.println("Sending!"); try { member.sendMessage("from server : happy and happiness! "+new Date()+newLine); } catch (IOException e) { e.printStackTrace(); } } } } }, 2, 2, TimeUnit.SECONDS); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { getServletContext().getNamedDispatcher("default").forward(request, response); } public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) { return new TailorSocket(); } class TailorSocket implements WebSocket.OnTextMessage { private Connection _connection; public void onClose(int closeCode, String message) { _members.remove(this); } public void sendMessage(String data) throws IOException { _connection.sendMessage(data); } public void onMessage(String data) { System.out.println("Received: "+data); } public boolean isOpen() { return _connection.isOpen(); } public void onOpen(Connection connection) { _members.add(this); _connection = connection; try { connection.sendMessage("onOpen:Server received Web Socket upgrade and added it to Receiver List."); } catch (IOException e) { e.printStackTrace(); } } } }
test.html
<!DOCTYPE HTML> <html> <head> <meta charset = "utf-8"/> <title>Chat by Web Sockets</title> <script type='text/javascript'> if (!window.WebSocket) alert("window.WebSocket unsuport!"); function $() { return document.getElementById(arguments[0]); } function $F() { return document.getElementById(arguments[0]).value; } function getKeyCode(ev) { if (window.event) return window.event.keyCode; return ev.keyCode; } var server = { connect : function() { var location ="ws://localhost:8888/servlet/a"; this._ws =new WebSocket(location); this._ws.onopen =this._onopen; this._ws.onmessage =this._onmessage; this._ws.onclose =this._onclose; }, _onopen : function() { server._send('send to server : websockets are open for communications!'); }, _send : function(message) { if (this._ws) this._ws.send(message); }, send : function(text) { if (text !=null&& text.length >0) server._send(text); }, _onmessage : function(m) { if (m.data) { var messageBox = $('messageBox'); var spanText = document.createElement('span'); spanText.className ='text'; spanText.innerHTML = m.data; var lineBreak = document.createElement('br'); messageBox.appendChild(spanText); messageBox.appendChild(lineBreak); messageBox.scrollTop = messageBox.scrollHeight - messageBox.clientHeight; } }, _onclose : function(m) { this._ws =null; } }; </script> <style type='text/css'> div { border: 0px solid black; } div#messageBox { clear: both; width: 40em; height: 20ex; overflow: auto; background-color: #f0f0f0; padding: 4px; border: 1px solid black; } div#input { clear: both; width: 40em; padding: 4px; background-color: #e0e0e0; border: 1px solid black; border-top: 0px } div.hidden { display: none; } span.alert { font-style: italic; } </style> </head> <body> <div id='messageBox'></div> <div id='input'> <div> <input id='connect' type='submit' name='Connect' value='Connect' /> </div> </div> <script type='text/javascript'> $('connect').onclick =function(event) { server.connect(); returnfalse; }; </script> <p> JAVA Jetty for WebSocket </p> </body> </html>
xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name>tailor</display-name> <servlet> <servlet-name>WebSocket</servlet-name> <servlet-class>com.test.TailorWebSocketServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>WebSocket</servlet-name> <url-pattern>/servlet/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>test.html</welcome-file> </welcome-file-list> </web-app>
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"> <!-- ================================================================== Configure and deploy the test web application in $(jetty.home)/webapps/test Note. If this file did not exist or used a context path other that /test then the default configuration of jetty.xml would discover the test webapplication with a WebAppDeployer. By specifying a context in this directory, additional configuration may be specified and hot deployments detected. ===================================================================== --> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- Required minimal context configuration : --> <!-- + contextPath --> <!-- + war OR resourceBase --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <Set name="contextPath">/</Set> <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set> <Set name="overrideDescriptor"><SystemProperty name="jetty.home" default="."/>/contexts/test.d/override-web.xml</Set> <!-- virtual hosts <Set name="virtualHosts"> <Array type="String"> <Item>www.myVirtualDomain.com</Item> <Item>localhost</Item> <Item>127.0.0.1</Item> </Array> </Set> --> <!-- disable cookies <Get name="sessionHandler"> <Get name="sessionManager"> <Set name="usingCookies" type="boolean">false</Set> </Get> </Get> --> <Get name="securityHandler"> <Set name="loginService"> <New class="org.eclipse.jetty.security.HashLoginService"> <Set name="name">Test Realm</Set> <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set> <!-- To enable reload of realm when properties change, uncomment the following lines --> <!-- changing refreshInterval (in seconds) as desired --> <!-- <Set name="refreshInterval">5</Set> <Call name="start"></Call> --> </New> </Set> <Set name="checkWelcomeFiles">true</Set> </Get> <!-- Non standard error page mapping --> <!-- <Get name="errorHandler"> <Call name="addErrorPage"> <Arg type="int">500</Arg> <Arg type="int">599</Arg> <Arg type="String">/dump/errorCodeRangeMapping</Arg> </Call> </Get> --> <!-- Add context specific logger <Set name="handler"> <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"> <Set name="requestLog"> <New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog"> <Set name="filename"><Property name="jetty.logs" default="./logs"/>/test-yyyy_mm_dd.request.log</Set> <Set name="filenameDateFormat">yyyy_MM_dd</Set> <Set name="append">true</Set> <Set name="LogTimeZone">GMT</Set> </New> </Set> </New> </Set> --> </Configure>
6단계:
이후 효과 실행 중: 브라우저 액세스: localhost:8080Eclipse 콘솔에서:
축하합니다 , 당신은 여기서 성공했습니다!
3. 성능이러한 유형의 연결에서는 Java에서 JDK Check Jconsole을 사용할 수 있습니다. bin 디렉토리. 단일 연결의 메모리 소비는 약 2.5M이지만 동시성은 테스트되지 않았습니다. 더 이상 사진이 없습니다
위 내용은 jetty7에 구현된 html5 WebSocket의 코드 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!