1. Introduction à WebSocket
Pour certains systèmes qui nécessitent beaucoup de données en temps réel, tels que les cotations boursières, le chat en ligne et Weibo, les données peuvent être réalisé Le push en temps réel est indispensable. Les moyens habituels d'obtenir un push en temps réel sont :
1. Polling : envoyer des données de temps en temps (comme : webqq)
2. Socket : dans le passé, le Web ordinaire les pages ne prenaient pas en charge les sockets Recevoir un message . Vous pouvez utiliser Flash ou applet comme client socket
3. Connexion longue : Cela signifie que plusieurs paquets de données peuvent être envoyés en continu sur une connexion TCP pendant la période de maintenance de la connexion TCP, si aucun paquet de données n'est envoyé, les deux parties doivent envoyer des paquets de détection pour maintenir cette connexion, vous devez généralement le faire vous-même
maintenance en ligne.
------------------------------------------------------ ------ -------------------------------------------- ------
html5 fournit une connexion bidirectionnelle non http via window.WebSocket (window.MozWebSocket sous Firefox Cette connexion est en temps réel et permanente sauf si elle est affichée). colse.
Cela signifie que tant que le client ouvre un Socket et demande une connexion (une seule fois), le serveur peut recevoir et envoyer des messages en temps réel sans détection ni maintenance manuelles Statut .
Les méthodes et les propriétés fournies par WebSocket peuvent être consultées en entrant Window.WebSocket.prototype dans firebug.
Le code suivant répertorie les idées d'utilisation de base :
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. Un exemple basé sur Jetty (serveur Java)
Actuellement, Apache ne prend pas en charge WebSocket. Différents langages ont leurs propres façons de l'implémenter, qui est implémenté en Java.
Étape 1 : Téléchargez une jetée, décompressez-la et placez-la sur n'importe quel disque. Jetty7 et supérieur ne prennent en charge que WebSocket, adresse de téléchargement : download.eclipse.org/jetty/stable-7/dist/
Étape 2 : Télécharger Eclipse (MyEclipse n'est pas recommandé, c'est plus gênant, il faut installer d'autres plug-ins) et doit prendre en charge jetty7. Plus la version est élevée, mieux c'est.
Étape 3 : Installez le plug-in dans Eclipse, aide---Installez le nouveau logiciel...----L'URL est : eclipse-jetty.sourceforge.net/update /
Étape 4 : Créer un nouveau projet Web dynamique
Étape 5 : Copiez le code suivant : TailorWebSocketServlet.java
test. html
web.socket.xmlpackage 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(); } } } }
<!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 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>
Sur la console Eclipse :
Félicitations, vous avez réussi ici !
3. Performances
Pour ce type de connexion, différents serveurs consomment des performances différentes. En Java, vous pouvez utiliser JDK Check Jconsole dans le. bin. La consommation de mémoire d'une seule connexion est d'environ 2,5 Mo, mais la concurrence n'a pas été testée. Plus de photos iciCe qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!