Die von WebSocket und Java ausgefüllte Meldungsputzfunktion wird vom Server Tomcat7.0 verwendet. Einige Dinge werden von selbst betrachtet, und ich weiß nicht, ob sie angemessen oder unangemessen sind. Bitte vergib mir und richten Sie sie darauf hin.
In einfachen Worten kann Kunde A Nachrichten an Kunden B senden, aber es gibt viele Orte, die erweitert werden können.
Zum Beispiel
1. Wenn nach dem Beitritt zur Datenbank, wenn A die Nachricht sendet, wird der Server die Nachricht in der Datenbank nicht online gespeichert. Nachdem der Kunden B online ist, wird die Nachricht abgerufen und an den Kunden B. gesendet
2. Der Server kann auch Nachrichten an jeden Client senden.
Der Screenshot des Programms des Programms ist wie folgt (getestet unter Chrome, Sogou und Firefox): Der Code wird am Ende angegeben
Zunächst öffnen wir einen Browser und zeigen an, um Ihren Namen einzugeben. Hier betrete ich Soar
Beim Öffnen des zweiten Browsers trete hier Bill ein
Dies ist, wenn ich Hallo Rechnung sende Ich bin auf Bill. Klicken Sie auf Senden klicken
Sie können es auf einem anderen Browser sehen
Websocket
1.Was ist Websocket?
WebSocket ist eine Technologie, die generiert wird, um die Echtzeitkommunikation zwischen Kunden und Servern zu lösen. Die Essenz besteht darin, eine TCP -Verbindung zum Austausch von Daten nach der Handshackung durch das HTTP/HTTPS -Protokoll zu erstellen.
Danach kommunizieren der Server und der Client in Echtzeit über diese TCP -Verbindung.
2. Vorteile von WebSocket
In der Vergangenheit haben wir die Push -Technologie unter Verwendung von Umfragen implementiert. Im charakteristischen Zeitintervall stellt der Browser automatisch eine Anforderung aus und zieht die Nachrichten des Servers aktiv zurück. In diesem Fall müssen wir ständig Anfragen an den Server senden. Der Header der HTTP -Anfrage ist jedoch sehr lang, und die darin enthaltenen Daten können nur ein kleiner Wert sein, der eine Menge Bandbreiten- und Serverressourcen einnimmt. Es wird viel Bandbreite und Serverressourcen verbrauchen.
Das Beste an der WebSocket -API ist, dass der Server und der Client immer innerhalb eines bestimmten Zeitbereichs Informationen zueinander bringen können. Nach der Erstellung der Verbindung kann der Server Daten aktiv an den Client übertragen.
Darüber hinaus ist die zwischen dem Server und dem Client ausgetauschten Headerinformationen sehr klein.
WebSocket ist nicht auf die Kommunikation im Ajax (oder XHR) -Modus beschränkt, da die AJAX -Technologie Kunden anfordern müssen, während WebSocket -Server und Clients Informationen zueinander bringen können.
Eine detaillierte Einführung in die Nachrichten von AJAX, Comet, WebSocket und WebSocket finden Sie unter http://www.shaoqun.com/a/54588.aspx Web Design] Ajax, Comet und WebSocket.
Wenn ich in Zukunft Zeit habe, werde ich es ausschreiben.
3.. So verwenden Sie WebSocket
Kunde
In einem Browser, der WebSocket nach dem Erstellen der Socket unterstützt. Sie können auf vier Veranstaltungen auf Sockets reagieren: Onopen, OnMessage und Onclose, dh OnError.
Ein einfaches Beispiel
var ws = new WebSocket (WS: // localhost: 8080); Ws.onopen = function () {console.log (offen); ws.send (Hallo);}; ws.onMessage = function (evt) {console.log (evt.data)};1.Var WS = New WebSocket (WS: // localhost: 8080);
Um ein WebSocket -Objekt zu beantragen, sind die Parameter die Adresse des Servers, die angeschlossen werden muss. Genau wie das HTTP -Protokoll beginnt die URL des WebSocket -Protokolls mit WS: // und das Secure WebSocket -Protokoll beginnt mit WSS: //.
Ws.send (Hallo);
Wird verwendet, um Nachrichten an den Server zu senden
2.Ws.onopen = function () {console.log (offen)};
Wenn das WebSocket erfolgreich erstellt wird, wird das Onopen -Ereignis ausgelöst
3.ws.onMessage = function (evt) {console.log (evt.data)};
Wenn der Client eine vom Server gesendete Nachricht erhält, wird das OnMessage -Ereignis ausgelöst. Der Parameter evt.data enthält die vom Server übertragenen Daten.
4.Ws.Onclose = function (evt) {console.log (WebSocketclosed!); };
Wenn der Client eine Anfrage erhält, um die vom Server gesendete Verbindung zu schließen, wird das Onclose -Ereignis ausgelöst
5.ws.onerror = function (evt) {console.log (WebSocketerror!); };
Wenn die Verbindung, Verarbeitung, Empfangen und Senden von Daten ausfällt, wird das OnError -Ereignis ausgelöst
Wir können sehen, dass alle Vorgänge durch Ereignisse ausgelöst werden, damit die Benutzeroberfläche nicht blockiert wird, sodass die Benutzeroberfläche eine schnellere Reaktionszeit und eine bessere Benutzererfahrung hat.
Serverseite
Heutzutage gibt es viele Serversoftware, die WebSocket unterstützt, wie Node.js, Steg, Tomcat usw.
Hier verwende ich Tomat 7.0 und Eclipse4.2
Tomcat, verwenden Sie WebSocket zuerst, um das relevante Glas zu importieren
Die von Tomcat7 bereitgestellten Klassen im Zusammenhang mit WebSocket befinden sich alle im Paket org.apache.catalina.websocket (Die Implementierung von Paket org.apache.catalina.websocket ist in der Datei catalina.jar enthalten
Hier importieren wir einfach alle Tomcat
In Build Path-> Build-Path-> Librarise-> Library-> Server RunTime-> Apache Tomcat v7.0 hinzufügen
Bild
Importieren Sie auch die folgenden Pakete
import org.apache.catalina.websocket.messageInbound;
import org.apache.catalina.websocket.streaminbound;
import org.apache.catalina.websocket.wsoutbound;
import org.apache.catalina.websocket.websocketServlet;
Wir brauchen zwei Klassen
Der erste wird verwendet, um WebSocket -Anfragen zu bearbeiten
Die zweite wird verwendet, um jede bestimmte WebSocket -Aufgabe zu übernehmen
Die erste Kategorie
SocketServer im öffentlichen Klassen erweitert WebSocketServlet {
private statische endgültige lange Serialversionuid = 1L;
//…
@Override
Protected Streaminbound Createwebsocketinbound (String arg0,
HttpServletRequest arg1) {
// Todo automatisch generierte Methode Stub
Rückgabe neuer Chatwebsocket (Benutzer);
}
}
Dieses Servlet erbt aus WebSocketServlet und implementiert die Methode createwebsocketinbound. Diese Methode gibt eine Instanz der zweiten Klasse zurück.
Die zweite Kategorie
öffentliche Klasse Chatwebsocket erweitert MessageInbound {
@Override
Protected void OnTextMessage (Charbuffer Message) löst IoException {aus
}
@Override
geschützte void onopen (WSoutbound -Outbound) {
}
@Override
geschützte void onclose (int status) {
}
@Override
Protected Void OnbarinaryMessage (ByteBuffer arg0) löst ioException {aus
}
// Der Rest ist nur ein wenig
}
Protected void OnTextMessage (Charbuffer Message) löst IOException {} aus
SMS -Nachrichtenantwort
Protected Void OnBinaryMessage (ByteBuffer arg0) löst IOException {} aus
Binärnachrichtenantwort
geschützte void onopen (wSoutbound ausgehende) {}
Ereignisse, die durch die Herstellung einer Verbindung ausgelöst werden
Protected void Onclose (int Status) {}
Ereignisse beim Schließen der Verbindung abgefeuert
4. Programmcode
HTML -Teil
<! DocType html>
<html>
<kopf>
<meta charset = utf-8>
<script type = text/javaScript src = js/jquery.js> </script>
<script type = text/javaScript src = js/socket.js> </script>
<title> bis zum Titel "Dokument" </title>
</head>
<script Language = JavaScript>
</script>
<body>
<tabelle>
<tr>
<td> Nachricht </td>
<td> <Eingabe type = text id = message> </td>
</tr>
<tr>
<td> Name </td>
<td> <Eingabe type = text id = othername> </td>
</tr>
<tr>
<td> <input id = sendButton type = button value = send onclick = klicken diallabled = true>
</input> </td>
</tr>
</table>
<Script>
</script>
</body>
</html>
JS -Teil (keine Erklärung zu JQuery Teil)
var userername = window.prompt (Geben Sie Ihren Namen ein :);
document.write (willkommen <p id =/usustname/>+userername+</p>);
if (! window.websocket && window.mozwebsocket)
window.websocket = window.mozwebsocket;
if (! window.websocket)
Alarm (keine Unterstützung);
var ws;
$ (Dokument) .Ready (function () {
$ (#sendbutton) .attr (behindert, falsch);
$ (#sendbutton) .click (sendMessage);
startWebsocket ();
})
Funktion sendMessage ()
{
var othername = $ (#othername) .val ();
var msg = msg/t+userername+_+othername+_+$ (#meldung) .val ();
send (msg);
}
Funktion senden (Daten)
{
console.log (send:+data);
ws.send (Daten);
}
Funktion startWebsocket ()
{
ws = new WebSocket (WS: // + location.host +/webocket/steckelnerver);
ws.onopen = function () {
console.log (Erfolg offen);
$ (#sendbutton) .attr (behindert, falsch);
};
Ws.onMessage = Funktion (Ereignis)
{
console.log (empfangen:+event.data);
Handledata (Event.Data);
};
ws.onclose = function (Ereignis) {
console.log (Client benachrichtigte Socket hat geschlossen, Ereignis);
};
}
Funktion gehandhabt (Daten)
{
var vals = data.split (/t);
var msgType = vals [0];
Schalter (MSGTYPE)
{
Fallname:
var msg = vals [1];
var mes = name+/t+msg+_+userername;
send (mes);
brechen;
Fall MSG:
var val2s = vals [1] .Split (_);
var von = val2s [0];
var message = val2s [2];
alarm (von+:+meldung);
brechen;
Standard:
brechen;
}
}
Java -Teil
importieren java.io.ioException;
Import Java.nio.ByTebuffer;
Import Java.nio.CharBuffer;
importieren javax.servlet.http.httpServletRequest;
Java.util.set importieren;
import Java.util.concurrent.copyonWriteArraySet;
import org.apache.catalina.websocket.messageInbound;
import org.apache.catalina.websocket.streaminbound;
import org.apache.catalina.websocket.wsoutbound;
import org.apache.catalina.websocket.websocketServlet;
SocketServer im öffentlichen Klassen erweitert WebSocketServlet {
private statische endgültige lange Serialversionuid = 1L;
Public Final Set <Chatwebsocket> user = new CopyonWriteArraySet <Chatwebsocket> ();
public static int usernumber = 1;
@Override
Protected Streaminbound Createwebsocketinbound (String arg0,
HttpServletRequest arg1) {
// Todo automatisch generierte Methode Stub
Rückgabe neuer Chatwebsocket (Benutzer);
}
öffentliche Klasse Chatwebsocket erweitert MessageInbound {
privater String -Benutzername;
private set <chatwebsocket> user = new CopyonWriteArraySet <Chatwebsocket> () ;;
public chatwebsocket () {
}
public chatwebocket (set <chatwebsocket> Benutzer) {
this.users = Benutzer;
}
@Override
Protected void OnTextMessage (Charbuffer Message) löst IoException {aus
// Was hier verarbeitet wird, sind Textdaten
}
public void OnMessage (String -Daten) {
String [] val1 = data.split (// t);
if (val1 [0] .Equals (Name))
{
String [] val2 = val1 [1] .Split (_);
für (Chatwebsocket -Benutzer: Benutzer) {
if (user.username.equals (val2 [0])) {
user.username = val2 [1];
}
}
}
sonst wenn (val1 [0] .Equals (msg))
{
String [] val2 = val1 [1] .Split (_);
für (Chatwebsocket -Benutzer: Benutzer) {
if (user.username.equals (val2 [1])) {
versuchen {
Charbuffer temp = charBuffer.wrap (Daten);
user.getWSoutBound (). WriteTextMessage (temp);
} catch (ioException e) {
// todo automatisch generierter Fangblock
E. printstacktrace ();
}
}
}
}
anders
{
System.out.println (Fehler);
}
}
@Override
geschützte void onopen (WSoutbound -Outbound) {
// this.connection = Verbindung;
this.username = # + string.valueof (userernumber);
Benutzernummer ++;
versuchen {
String message = name + /t + this.username;
CharBuffer buffer = charBuffer.wrap (message);
this.getWSoutBound (). WriteTextMessage (Puffer);
} catch (ioException e) {
// todo automatisch generierter Fangblock
E. printstacktrace ();
}
user.add (this);
}
@Override
geschützte void onclose (int status) {
user.remove (this);
}
@Override
Protected Void OnbarinaryMessage (ByteBuffer arg0) löst ioException {aus
}
}
}
erklären
Meine Idee hier ist
1 Beim Zugriff muss jeder Benutzer zuerst seinen Namen eingeben und dann eine Verbindungsanforderung an den Server senden.
2 Nachdem der Server die Verbindungsanforderung des Clients angenommen hat, wird es neue Chatwebsocket (Benutzer) erhalten. Um diese Anfrage zu bearbeiten und der Online -Benutzerliste hinzuzufügen. Zu diesem Zeitpunkt kennt der Server den Namen des Kunden noch nicht. Es wird ein Name für diesen Benutzer, Nr. 1, angenommen, und der Server sendet den Namen + /T + #1 an den Client. Wie heißt Ihr Name?
3 Wenn der Client diese Nachricht empfängt, wird er wissen, dass der Server sich fragt, wie er heißt, so dass der Client den Namen+/T+#1+_+seinen eigenen Namen an den Server sendet (mein Name ist xxx)
4 Nach dem Empfang dieser Nachricht basiert der Server in der aktuell Online -Benutzerliste basierend auf Nr. 1 und ersetzt #1 durch den Namen des Kunden, damit der Server den Namen des Kunden kennt.
5 Wenn der Kunde geht, löst der Server das OnClose -Ereignis aus, und der Server entzieht den aktuellen Benutzer aus der Online -Liste.
Verwenden Sie Bilder, um so etwas zu zeichnen (schlecht gezeichnet, -_- !!)
Code
JS
ws = new WebSocket (WS: // + location.host +/webocket/steckelnerver);
Stellen Sie eine Verbindung zum Server her
Java
Protected Streaminbound Createwebsocketinbound (String arg0,
HttpServletRequest arg1) {
// Todo automatisch generierte Methode Stub
Rückgabe neuer Chatwebsocket (Benutzer);
}
Erstellen Sie ein ChatWebsocket, um diese Anforderung zu bearbeiten und das Onopen -Ereignis des ChatWebsocket -Objekts auszulösen
@Override
geschützte void onopen (WSoutbound -Outbound) {
// this.connection = Verbindung;
this.username = # + string.valueof (userernumber);
Benutzernummer ++;
versuchen {
String message = name + /t + this.username;
CharBuffer buffer = charBuffer.wrap (message);
this.getWSoutBound (). WriteTextMessage (Puffer);
} catch (ioException e) {
// todo automatisch generierter Fangblock
E. printstacktrace ();
}
user.add (this);
}
Unter der Annahme eines Namens für diesen Client, Senden des angenommenen Namens des Namens+/T+ an den Client und Hinzufügen des Clients zur aktuell verbundenen Clientliste
JS
Funktion gehandhabt (Daten)
{
var vals = data.split (/t);
var msgType = vals [0];
Schalter (MSGTYPE)
{
Fallname:
var msg = vals [1];
var mes = name+/t+msg+_+userername;
send (mes);
brechen;
// ………
}
}
Akzeptieren und verarbeiten Sie die vom Server gesendete Nachricht und stellen Sie fest, dass der Server sie gefragt hat, wie er Name ist. Daher senden Sie den Namen+/T+den angenommenen Namen+_+an den Server.
Java
public void OnMessage (String -Daten) {
String [] val1 = data.split (// t);
if (val1 [0] .Equals (Name))
{
String [] val2 = val1 [1] .Split (_);
für (Chatwebsocket -Benutzer: Benutzer) {
if (user.username.equals (val2 [0])) {
user.username = val2 [1];
}
}
}
// ………
}
Verarbeiten und akzeptieren Sie die vom Client gesendete Nachricht und stellen Sie fest, dass der Client auf seinen Namen geantwortet hat. Suchen Sie daher in der aktuell verbundenen Client -Liste basierend auf dem zuvor angenommenen Namen und wenden Sie das Pseudonym in den richtigen Namen zu
JS
Funktion sendMessage ()
{
var othername = $ (#othername) .val ();
var msg = msg/t+userername+_+othername+_+$ (#meldung) .val ();
send (msg);
}
Der Kunde initiiert eine Konversation mit einer anderen Person, und das Nachrichtenformat lautet: MSG+sein eigener Name+_+gegenüberliegende Name+_+Nachricht
Java
public void OnMessage (String -Daten) {
/// …………
sonst wenn (val1 [0] .Equals (msg))
{
String [] val2 = val1 [1] .Split (_);
für (Chatwebsocket -Benutzer: Benutzer) {
if (user.username.equals (val2 [1])) {
versuchen {
Charbuffer temp = charBuffer.wrap (Daten);
user.getWSoutBound (). WriteTextMessage (temp);
} catch (ioException e) {
// todo automatisch generierter Fangblock
E. printstacktrace ();
}
}
}
}
/// …………
}
Es wird festgestellt, dass die Nachricht vom Kunden gesendet wird. Nach dem Namen der anderen Partei suchen Sie in der aktuell verbundenen Kundenliste und senden Sie die Nachricht an ihn.
JS
Funktion gehandhabt (Daten)
{
var vals = data.split (/t);
var msgType = vals [0];
Schalter (MSGTYPE)
{
///…
Fall MSG:
var val2s = vals [1] .Split (_);
var von = val2s [0];
var message = val2s [2];
alarm (von+:+meldung);
brechen;
Standard:
brechen;
}
}
Es wurde festgestellt, dass es sich um eine Nachricht handelte, die von einem anderen Kunden gesendet wurde, und sie wurde über Alarm angezeigt
Java
@Override
geschützte void onclose (int status) {
user.remove (this);
}
Entdecken Sie, dass der Kunde den Kunden aus der verbundenen Kundenliste entfernen hat
Wo zu verbessern
1. Wenn Client A eine Nachricht an B und B nicht online sendet, kann die Nachricht in der Datenbank gespeichert werden. Wenn sich B als online befindet, wird es aus der Datenbank abgerufen und an B. gesendet
2 Wenn der Server Ihren Namen sendet, kann er einen Zeitüberschreitungsmechanismus hinzufügen. Wenn der Kunde nicht auf das antwortet, was er innerhalb eines bestimmten Zeitraums aufgerufen wird, kann der Kunde den Kunden aus der Online -Liste löschen.