站長資訊網
最全最豐富的資訊網站

html5 WebSocket在jetty7中實現的代碼分享

一、WebSocket簡介

對于一些對數據實時性要求較高的系統,比如股票行情、在線聊天、微博,實現數據的實時推送是必須的。通常實現實時推送的方式有:

1、輪詢:隔一段時間發送數據(如:webqq)

2、socket:以往普通的網頁是不支持socket接收消息的。可以通過flash或者applet來作為socket的客戶端

3、長連接:指在一個TCP連接上可以連續發送多個數據包,在TCP連接保持期間,如果沒有數據包發送,需要雙方發檢測包以維持此連接,一般需要自己做

在線維持。

———————————————————————————————-

html5通過window.WebSocket(firefox下是window.MozWebSocket)提供了一種非http的雙向連接,這個連接是實時的更是永久的,除非被顯示colse。

這就表示只要客戶端打開一個Socket并且請求建立了連接(just once),服務端就能實時接收并發送消息,不需手動檢測和維持狀態。

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();

二、一個基于jetty(java服務器)的例子

目前Apache還不支持WebSocket,各種語言都有各自的方式可以實現它,這里在Java中實現了。

步驟一:下載一個jetty,解壓放在任意盤下。jetty7及以上才支持WebSocket,下載地址:download.eclipse.org/jetty/stable-7/dist/

步驟二:下載eclipse(不推薦用MyEclipse,比較麻煩,需要安裝其他的插件),必須支持jetty7,版本是越高越好。

步驟三:在eclipse中安裝插件,help—Install new software…—-url為:eclipse-jetty.sourceforge.net/update/

步驟四:新建一個Dynamic Web Project

目錄結構如下

html5 WebSocket在jetty7中實現的代碼分享

步驟五:拷入如下代碼:

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>

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

<?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>

步驟六:

html5 WebSocket在jetty7中實現的代碼分享

跑后的效果:

瀏覽器訪問:localhost:8080

html5 WebSocket在jetty7中實現的代碼分享

eclipse控制臺上:

html5 WebSocket在jetty7中實現的代碼分享

恭喜你,到這兒就算success了!

三、性能

對于這種類型的連接,各種服務器需要消耗的性能也不同,java下可以通過JDK的bin目錄下的Jconsole來查看,單個連接內存消耗在2.5M左右,但是對于并發量還沒有做測試。這里不貼圖了

贊(0)
分享到: 更多 (0)
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
精品久久久久一区二区三区 | 国产精品免费一级在线观看| 久久精品国产亚洲av影院 | 国产精品视频一区二区三区无码| 亚洲高清国产拍精品青青草原| 日韩av无码久久精品免费| 国产成人一区二区三区精品久久| 精品真实国产乱文在线| 午夜精品久久久久久中宇| 久久精品国产99国产电影网| 无码精品人妻一区二区三区影院| 日韩亚洲一区二区三区| 国产成人午夜精品一区二区三区| 亚洲日韩国产精品无码av| 久久精品国产96精品亚洲| 国产在线无码精品电影网| 日韩在线观看高清视频| 国产乱人伦app精品久久| 日韩精品专区在线影院重磅| 国产精品一级香蕉一区| 亚洲精品电影在线| 99在线热视频只有精品免费| 99精品国产高清一区二区三区 | 亚洲精品动漫人成3d在线| 国产精品一区二区香蕉| 日韩国产精品亚洲а∨天堂免| 国产精品久久新婚兰兰| 97热久久免费频精品99| 2020天堂在线亚洲精品专区| 精品久久久久久婷婷| 久久99国产这里有精品视| 久久亚洲国产精品| 久久精品国产亚洲| 国内精品久久久久久野外| 国产成人精品午夜福麻豆| 精品国产一区二区22| 东京热TOKYO综合久久精品| 三级精品视频在线播放| 日韩精品一区二区三区毛片| 精品久久久久久中文字幕一区| 国产精品国产午夜免费福利看|