1. Was ist WebSocket?
WebSocket ist eine natürliche Vollduplex-Zwei-Wege-Single-Socket-Verbindung. Mit WebSocket wird Ihre HTTP-Anfrage zu einer einzelnen Anfrage zum Öffnen einer WebSocket-Verbindung (WebSocket oder WebSocket über TLS (Transport Layer Security, früher bekannt als „SSL“) und zur Wiederverwendung der Verbindung von Client zu Server und von Server zu Client. WebSocket reduziert die Latenz, da der Server Nachrichten senden kann, sobald eine WebSocket-Verbindung hergestellt ist, sobald diese verfügbar sind. Im Gegensatz zum Polling stellt WebSocket beispielsweise nur eine einzige Anfrage. Der Server muss nicht auf Anfragen von Clients warten. Ebenso kann der Client jederzeit Nachrichten an den Server senden. Im Vergleich zum gelegentlichen Abfragen und Senden einer Anfrage, unabhängig davon, ob eine Nachricht verfügbar ist, reduziert eine einzelne Anfrage die Latenz erheblich.
2. WebSocket-API
Mit der WebSocket-API können Sie eine bidirektionale Vollduplex-Kommunikation zwischen Clientanwendungen und serverseitigen Prozessen über das Web einrichten. Die WebSocket-Schnittstelle gibt die dem Client zur Verfügung stehenden Methoden und die Art und Weise an, wie der Client mit dem Netzwerk interagiert.
3. WebSocket-Konstruktor
Um eine WebSocket-Verbindung zum Server herzustellen, verwenden Sie die WebSocket-Schnittstelle, um ein WebSocket-Objekt zu instanziieren, indem Sie auf eine URL verweisen, die den zu verbindenden Endpunkt darstellt . Das WebSocket-Protokoll definiert zwei URL-Schemata – ws und wss –, die für unverschlüsselten bzw. verschlüsselten Datenverkehr zwischen dem Client und dem Server verwendet werden.
Beispiel: var ws = new WebSocket("ws://www.websocket.org");
4. WebSocket-Ereignisse
Die WebSocket-API ist rein ereignisgesteuert . Der Anwendungscode wartet auf Ereignisse im WebSocket-Objekt, um eingehende Daten und Änderungen im Verbindungsstatus zu verarbeiten. Das WebSocket-Protokoll ist ebenfalls ereignisgesteuert.
Das WebSocket-Objekt löst 4 verschiedene Ereignisse aus:
Ein offenes Ereignis:
Sobald der Server auf die WebSocket-Verbindungsanforderung antwortet, wird das offene Ereignis ausgelöst und stellt eine Verbindung her. Die dem offenen Ereignis entsprechende Rückruffunktion heißt onopen
instanz:
ws.onopen = function(e) { console.log("Connection open..."); };
Nachrichtensereignis:
Das Nachrichtenereignis wird ausgelöst, wenn eine Nachricht empfangen wird, und die diesem Ereignis entsprechende Rückruffunktion ist onmessage.
Beispiel:
ws.onmessage = function(e) { if(typeof e.data === "string"){ console.log("String message received", e, e.data); } else { console.log("Other message received", e, e.data); } };
Fehlerereignis:
Fehlerereignis wird als Reaktion auf verwendet Zeitauslöser für unerwartete Ausfälle. Die diesem Ereignis entsprechende Rückruffunktion ist onerror.
Instanz:
ws.onerror = function(e){ console.log('websocked error'); handerError(); }
D. Schließereignis:
Schließereignis wird ausgelöst, wenn die WebSocket-Verbindung geschlossen wird. Die dem Schließereignis entsprechende Rückruffunktion ist onclose.
Instanz:
ws.onclose = function(e) { console.log("Connection closed", e); };
5. WebSocket-Methode
Das WebSocket-Objekt verfügt über zwei Methoden: send() und schließen().
A. send()-Methode:
Nachdem Sie WebSocket zum Herstellen einer bidirektionalen Vollduplex-Verbindung zwischen dem Client und dem Server verwendet haben, können Sie beim Herstellen der Verbindung die send()-Methode aufrufen wird geöffnet. Verwenden Sie die Methode send(), um Nachrichten vom Client an den Server zu senden. Nachdem Sie eine oder mehrere Nachrichten gesendet haben, können Sie die Verbindung offen halten oder die Methode close() aufrufen, um die Verbindung zu beenden.
Beispiel:
ws.send("Hello WebSocket!");
B. close()-Methode:
Verwenden Sie zum Schließen die close()-Methode WebSocket-Verbindung oder Verbindungsversuch beenden. Wenn die Verbindung geschlossen wurde, führt diese Methode keine Aktion aus. Nach dem Aufruf von close() können auf einem geschlossenen WebSocket keine Daten mehr gesendet werden. An die Methode close() können zwei optionale Parameter übergeben werden: code (ein numerischer Statuscode) und reason (eine Textzeichenfolge). Die Übergabe dieser Parameter kann dem Server Informationen darüber übermitteln, warum der Client die Verbindung geschlossen hat.
Hinweis: Das Obige ist eine kurze Einführung in WebSocket. Im Folgenden wird anhand eines einfachen Webseiten-Echtzeit-Chats erläutert, wie WebSocket verwendet wird.
A: Erstellen Sie zunächst einen Neues Projekt. Ich nenne es Chatroom. Ich erstelle ein Paket und erstelle dann eine neue Klasse, um die serverseitige Verbindung zu implementieren.
Das spezifische Projekt wird wie folgt erstellt:
B: Schreiben Sie die serverseitige Implementierungsklasse ChatWebSocketServlet.java. Der spezifische Code lautet wie folgt:
package com.yc.chat.Servlet; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import org.apache.catalina.websocket.MessageInbound; import org.apache.catalina.websocket.StreamInbound; import org.apache.catalina.websocket.WebSocketServlet; import org.apache.catalina.websocket.WsOutbound; @WebServlet("/chat") public class ChatWebSocketServlet extends WebSocketServlet { private final Map<Integer, WsOutbound> map = new HashMap<Integer, WsOutbound>(); private static final long serialVersionUID = -1058445282919079067L; @Override protected StreamInbound createWebSocketInbound(String arg0, HttpServletRequest request) { // StreamInbound:基于流的WebSocket实现类(带内流),应用程序应当扩展这个类并实现其抽象方法onBinaryData和onTextData。 return new ChatMessageInbound(); } class ChatMessageInbound extends MessageInbound { // MessageInbound:基于消息的WebSocket实现类(带内消息),应用程序应当扩展这个类并实现其抽象方法onBinaryMessage和onTextMessage。 @Override protected void onOpen(WsOutbound outbound) { map.put(outbound.hashCode(), outbound); super.onOpen(outbound); } @Override protected void onClose(int status) { map.remove(getWsOutbound().hashCode()); super.onClose(status); } @Override protected void onBinaryMessage(ByteBuffer buffer) throws IOException { } @Override protected void onTextMessage(CharBuffer buffer) throws IOException { String msg = buffer.toString(); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); msg = " <font color=green>匿名用戶 " + sdf.format(date) + "</font><br/> " + msg; broadcast(msg); } private void broadcast(String msg) { Set<Integer> set = map.keySet(); for (Integer integer : set) { WsOutbound outbound = map.get(integer); CharBuffer buffer = CharBuffer.wrap(msg); try { outbound.writeTextMessage(buffer); outbound.flush(); } catch (IOException e) { e.printStackTrace(); } } } } }
Nicht verschönert, relativ einfach. Der spezifische Code lautet wie folgt:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>websocket聊天室</title> <style type="text/css"> #chat { text-align: left; width: 600px; height: 500px; width: 600px; } #up { text-align: left; width: 100%; height: 400px; border: 1px solid green; OVERFLOW-Y: auto; } #down { text-align: left; height: 100px; width: 100%; } </style> </head> <body> <h2 align="center">基于HTML5的聊天室</h2> <div align="center" style="width: 100%; height: 700px;"> <div id="chat"> <div id="up"></div> <div id="down"> <textarea type="text" style="width: 602px; height: 100%;" id="send"></textarea> </div> </div> <input type="button" value="连接" onclick="chat(this);"> <input type="button" value="发送" onclick="send(this);" disabled="disabled" id="send_btn" title="Ctrl+Enter发送"> </div> </body> <script type="text/javascript"> var socket; var receive_text = document.getElementById("up"); var send_text = document.getElementById("send"); function addText(msg) { receive_text.innerHTML += "<br/>" + msg; receive_text.scrollTop = receive_text.scrollHeight; } var chat = function(obj) { obj.disabled = "disabled"; socket = new WebSocket('ws://localhost:8080/chatroom/chat'); receive_text.innerHTML += "<font color=green>正在连接服务器……</font>"; //打开Socket socket.onopen = function(event) { addText("<font color=green>连接成功!</font>"); document.getElementById("send_btn").disabled = false; send_text.focus(); document.onkeydown = function(event) { if (event.keyCode == 13 && event.ctrlKey) { send(); } } }; socket.onmessage = function(event) { addText(event.data); }; socket.onclose = function(event) { addText("<font color=red>连接断开!</font>"); obj.disabled = ""; }; if (socket == null) { addText("<font color=red>连接失败!</font>"); } }; var send = function(obj) { if (send_text.value == "") { return; } socket.send(send_text.value); send_text.value = ""; send_text.focus(); } </script> </html>
Eine solche einfache Echtzeit-Chat-Seite ist fertig. Stellen Sie als Nächstes das Projekt auf dem Tomcat 7.0-Server bereit Aktivieren Sie den Server zum Chatten
Ergebnisanzeige:
1. Geben Sie die Serveradresse in die Adressleiste ein:
http://127.0.0.1:8080 /chatroom/index .jsp
Klicken Sie, um eine Verbindung zum Server herzustellen. Das Ergebnis sieht wie folgt aus:
2. In zwei verschiedenen Browsern öffnen und Informationen aneinander senden ( Ich verwende hier Google und Firefox) Die Ergebnisse sind wie folgt: