>  기사  >  웹 프론트엔드  >  jetty7에 구현된 html5 WebSocket의 코드 공유

jetty7에 구현된 html5 WebSocket의 코드 공유

黄舟
黄舟원래의
2017-04-01 11:13:211981검색

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=&#39;text/javascript&#39;>
            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(&#39;send to server : websockets are open for communications!&#39;);
                },

                _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 = $(&#39;messageBox&#39;);
                        var spanText = document.createElement(&#39;span&#39;);
                        spanText.className =&#39;text&#39;;
                        spanText.innerHTML = m.data;
                        var lineBreak = document.createElement(&#39;br&#39;);
                        messageBox.appendChild(spanText);
                        messageBox.appendChild(lineBreak);
                        messageBox.scrollTop = messageBox.scrollHeight
                                - messageBox.clientHeight;
                    }
                },

                _onclose : function(m) {
                    this._ws =null;
                }
            };
        </script>
        <style type=&#39;text/css&#39;>
            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=&#39;messageBox&#39;></div>
        <div id=&#39;input&#39;>
            <div>
                <input id=&#39;connect&#39; type=&#39;submit&#39; name=&#39;Connect&#39;
                    value=&#39;Connect&#39; />
            </div>
        </div>
        <script type=&#39;text/javascript&#39;>
            $(&#39;connect&#39;).onclick =function(event) {
                server.connect();
                returnfalse;
            };
        </script>

        <p>
            JAVA Jetty for WebSocket
        </p>
    </body>
</html>

web.

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>

websocket. 🎜>
<?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:8080

Eclipse 콘솔에서:

축하합니다 , 당신은 여기서 성공했습니다!

3. 성능

이러한 유형의 연결에서는 Java에서 JDK Check Jconsole을 사용할 수 있습니다. bin 디렉토리. 단일 연결의 메모리 소비는 약 2.5M이지만 동시성은 테스트되지 않았습니다. 더 이상 사진이 없습니다

위 내용은 jetty7에 구현된 html5 WebSocket의 코드 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.