La fonction de poussée de message remplie par WebSocket et Java est utilisée par le serveur Tomcat7.0. Certaines choses sont considérées par vous-même, et je ne sais pas si elles sont appropriées ou inappropriées. S'il vous plaît pardonnez-moi et signalez-les.
En termes simples, le client A peut envoyer des messages au client B, mais il existe de nombreux endroits qui peuvent être élargis.
Par exemple
1. Si après avoir rejoint la base de données, lorsqu'il envoie le message, le client B n'est pas en ligne, le serveur stockera le message dans la base de données. Une fois le client B en ligne, le message sera récupéré et envoyé au client B.
2. Le serveur peut également envoyer des messages à n'importe quel client.
La capture d'écran de l'effet de course du programme est la suivante (testée sous Chrome, Sogou et Firefox): le code sera donné à la fin
Tout d'abord, nous ouvrons un navigateur et affichons pour entrer votre nom. Ici, je participe à Soar
Lors de l'ouverture du deuxième navigateur, je sais ici Bill
C'est si j'envoie Hello Bill, je suis en train de monter à Bill, cliquez sur Envoyer
Vous pouvez le voir sur un autre navigateur
Websocket
1.Quelle est WebSocket?
WebSocket est une technologie générée pour résoudre la communication en temps réel entre les clients et les serveurs. L'essence consiste à créer une connexion TCP pour échanger des données après une étagère via le protocole HTTP / HTTPS.
Après cela, le serveur et le client communiquent en temps réel via cette connexion TCP.
2. Avantages de WebSocket
Dans le passé, nous avons mis en œuvre la technologie push, en utilisant le sondage. À l'intervalle de temps caractéristique, le navigateur émet automatiquement une demande et retire activement les messages du serveur. Dans ce cas, nous devons constamment envoyer des demandes au serveur. Cependant, l'en-tête de la demande HTTP est très long, et les données contenues peuvent être juste une petite valeur, qui occupera beaucoup de ressources de bande passante et de serveur. Il consommera beaucoup de ressources de bande passante et de serveur.
La meilleure chose à propos de l'API WebSocket est que le serveur et le client peuvent se repousser les uns aux autres à tout moment dans une plage de temps donnée. Après avoir établi la connexion, le serveur peut transmettre activement des données au client.
De plus, les informations d'en-tête échangées entre le serveur et le client sont très petites.
WebSocket ne se limite pas à la communication en mode Ajax (ou XHR), car la technologie AJAX exige que les clients lancent des demandes, tandis que les serveurs et les clients WebSocket peuvent se repousser les informations;
Pour une introduction détaillée aux messages Ajax, Comet, WebSocket et WebSocket, vous pouvez vous référer à http://www.shaoqun.com/a/54588.aspx conception Web] Ajax, Comet et WebSocket.
Si j'ai du temps à l'avenir, je l'écrirai.
3. Comment utiliser WebSocket
Client
Dans un navigateur qui prend en charge WebSocket, après avoir créé la prise. Vous pouvez répondre aux sockets à travers quatre événements: Onopen, OnMessage et OnClose, c'est-à-dire ONERROR.
Un exemple simple
var ws = new WebSocket (ws: // localhost: 8080); ws.onopen = function () {console.log (ouvert); Ws.Send (Hello);}; ws.OnMessage = function (evt) {console.log (evt.data)}; ws.OnClose = function (evt) {console.log (WebSocketClosed!);}; ws.OnError = function (evt) {console.log (WebSocketError!);};1.var ws = new WebSocket (ws: // localhost: 8080);
Pour postuler pour un objet WebSocket, les paramètres sont l'adresse du serveur qui doit être connecté. Tout comme le protocole HTTP, l'URL du protocole WebSocket commence par ws: //, et le protocole WebSocket sécurisé commence par WSS: //.
Ws.Send (bonjour);
Utilisé pour envoyer des messages au serveur
2.ws.onopen = function () {console.log (ouvert)};
Lorsque le WebSocket est créé avec succès, l'événement Onopen sera déclenché
3.ws.onMessage = function (evt) {console.log (evt.data)};
Lorsque le client reçoit un message envoyé par le serveur, l'événement OnMessage sera déclenché. Le paramètre EVT.DATA contient les données transmises par le serveur.
4.ws.Onclose = function (evt) {console.log (WebSocketClosed!); };
Lorsque le client reçoit une demande pour fermer la connexion envoyée par le serveur, l'événement OnClose est déclenché
5.ws.OnError = fonction (evt) {console.log (WebSocketError!); };
Si la connexion, le traitement, la réception et l'envoi de données échouent, l'événement OnError sera déclenché
Nous pouvons voir que toutes les opérations sont déclenchées par des événements, afin que l'interface utilisateur ne bloque pas, permettant à l'interface utilisateur d'avoir un temps de réponse plus rapide et une meilleure expérience utilisateur.
Côté serveur
De nos jours, il existe de nombreux logiciels de serveur qui prennent en charge WebSocket, tels que Node.js, Jetty, Tomcat, etc.
Ici, j'utilise Tomat 7.0 et Eclipse4.2
Tomcat, utilisez d'abord WebSocket pour importer le pot pertinent
Les classes liées à WebSocket fournies par Tomcat7 sont toutes situées dans le package org.apache.catalina.websocket (l'implémentation du package org.apache.catalina.websocket est contenu dans le fichier Catalina.jar
Ici, nous importons tout ce que Tomcat
Dans Build Path-> Configurer le chemin de construction -> Librarise-> Ajouter la bibliothèque-> Server Runtime-> Apache Tomcat v7.0
image
Importez également les packages suivants
import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.streaminbound;
import org.apache.catalina.websocket.wsoutbound;
import org.apache.catalina.websocket.websocketservlet;
Nous avons besoin de deux cours
Le premier est utilisé pour gérer les demandes WebSocket
Le second est utilisé pour gérer chaque tâche WebSocket spécifique
La première catégorie
Classe publique SocketsServer étend WebSocketServlet {
Long SerialVersionUID privé statique statique = 1L;
//…
@Outrepasser
protégé StreamInbound CreateEweBSocketInbound (String Arg0,
HttpservletRequest arg1) {
// Talage de méthode générée automatiquement de TODO
return new Chatwebsocket (utilisateurs);
}
}
Ce servlet hérite de WebSocketServlet et met en œuvre la méthode CreateWebSocketInbound. Cette méthode renvoie une instance de la deuxième classe.
La deuxième catégorie
classe publique Chatwebsocket étend MessageInbound {
@Outrepasser
Protected void onTextMessage (Message Charbuffer) lance ioException {
}
@Outrepasser
Vide protégée sur open (wsoutBound Outbound) {
}
@Outrepasser
protégé void onclose (int status) {
}
@Outrepasser
vide protégée onbinaryMessage (bytebuffer arg0) lève ioexception {
}
// le reste est juste un peu
}
Protected void onTextMessage (Message de Charbuffer) lève IOException {}
Réponse du message texte
Protégé void OnbinaryMessage (ByteBuffer Arg0) lève IOException {}
Réponse du message binaire
Protégé void onopen (WSOutBound Outbound) {}
Événements déclenchés en établissant une connexion
protégé void onclose (int status) {}
Événements tirés lors de la fermeture de la connexion
4. Code du programme
partie HTML
<! Doctype html>
<html>
<adal>
<Meta Charset = UTF-8>
<script type = text / javascript src = js / jQuery.js> </ script>
<script type = text / javascript src = js / socket.js> </ script>
<Title> UNT intitulé Document </Title>
</ head>
<Script Language = JavaScript>
</cript>
<body>
<ballage>
<tr>
<td> Message </td>
<td> <Type de Text = Text ID = Message> </td>
</tr>
<tr>
<td> nom </td>
<td> <Type de Text = Text ID = OUTRENAME> </TD>
</tr>
<tr>
<td> <ID Input = SendButton Type = Button Value = Send OnClick = Cliquez sur Disabled = TRUE>
</paine> </td>
</tr>
</ table>
<cript>
</cript>
</docy>
</html>
JS Part (aucune explication sur la partie jQuery)
var username = window.prompt (entrez votre nom :);
document.write (bienvenue <p id = / nom d'utilisateur /> + nom d'utilisateur + </p>);
if (! window.websocket && window.mozwebsocket)
window.websocket = window.mozwebsocket;
if (! window.websocket)
alerte (pas de support);
var ws;
$ (document) .ready (function () {
$ (# sendButton) .Attr (handicap, false);
$ (# sendButton) .click (sendMessage);
startwebsocket ();
})
fonction SendMessage ()
{
var autre autre = $ (# autre) .Val ();
var msg = msg / t + nom d'utilisateur + _ + autre Name + _ + $ (# message) .Val ();
envoyer (msg);
}
fonction Send (données)
{
console.log (envoyer: + données);
Ws.Send (données);
}
fonction startwebsocket ()
{
ws = new WebSocket (ws: // + location.host + / WebSocket / socketserver);
ws.onopen = function () {
Console.log (Success Open);
$ (# sendButton) .Attr (handicap, false);
};
ws.onMessage = fonction (événement)
{
console.log (recevoir: + event.data);
mandepredata (event.data);
};
ws.Onclose = fonction (événement) {
console.log (le socket notifié client a fermé, événement);
};
}
Fonction Managedata (données)
{
var vals = data.split (/ t);
var msgType = vals [0];
commutateur (msgtype)
{
Nom de cas:
var msg = vals [1];
var mes = name + / t + msg + _ + nom d'utilisateur;
Envoyer (MES);
casser;
Case MSG:
var val2s = vals [1] .split (_);
var de = val2s [0];
var message = val2s [2];
alert (de +: + message);
casser;
défaut:
casser;
}
}
Partie java
Importer java.io.ioException;
import java.nio.bytebuffer;
import java.nio.charbuffer;
Importer javax.servlet.http.httpservletRequest;
import java.util.set;
Importer 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;
Classe publique SocketsServer étend WebSocketServlet {
Long SerialVersionUID privé statique statique = 1L;
public final set <chatWebsocket> users = new CopyOnwriteArraySet <at ChatWebSocket> ();
Public static int userner = 1;
@Outrepasser
protégé StreamInbound CreateEweBSocketInbound (String Arg0,
HttpservletRequest arg1) {
// Talage de méthode générée automatiquement de TODO
return new Chatwebsocket (utilisateurs);
}
classe publique Chatwebsocket étend MessageInbound {
Nom d'utilisateur de chaîne privée;
set privé <chatwebsocket> utilisateurs = new CopyOnwriteArraySet <at Chatwebsocket> () ;;
public chatwebsocket () {
}
public chatwebsocket (set <chatwebsocket> utilisateurs) {
this.users = utilisateurs;
}
@Outrepasser
Protected void onTextMessage (Message Charbuffer) lance ioException {
// Ce qui est traité ici, ce sont les données de texte
}
public void OnMessage (Data String) {
String [] Val1 = data.split (// t);
if (val1 [0] .equals (nom))
{
String [] val2 = val1 [1] .split (_);
pour (chatwebsocket utilisateur: utilisateurs) {
if (user.userName.equals (val2 [0])) {
user.Username = Val2 [1];
}
}
}
else if (val1 [0] .equals (msg))
{
String [] val2 = val1 [1] .split (_);
pour (chatwebsocket utilisateur: utilisateurs) {
if (user.userName.equals (val2 [1])) {
essayer {
Charbuffer temp = Charbuffer.Wrap (données);
user.getWsoutBound (). WriteTextMessage (temp);
} catch (ioexception e) {
// Bloc de capture généré automatiquement de TODO
e.printStackTrace ();
}
}
}
}
autre
{
System.out.println (erreur);
}
}
@Outrepasser
Vide protégée sur open (wsoutBound Outbound) {
// this.connection = connexion;
this.userName = # + string.valueof (UserNumber);
UserNumber ++;
essayer {
String message = name + / t + this.userName;
Charbuffer Buffer = Charbuffer.Wrap (message);
this.getwsoutBound (). writeTextMessage (tampon);
} catch (ioexception e) {
// Bloc de capture généré automatiquement de TODO
e.printStackTrace ();
}
users.add (this);
}
@Outrepasser
protégé void onclose (int status) {
Users.Remove (this);
}
@Outrepasser
vide protégée onbinaryMessage (bytebuffer arg0) lève ioexception {
}
}
}
expliquer
Mon idée ici est
1 Lors de l'accès, chaque utilisateur doit d'abord saisir son nom, puis envoyer une demande de connexion au serveur.
2 Une fois que le serveur a accepté la demande de connexion du client, il sera nouveau ChatWebsocket (utilisateurs); Pour traiter cette demande et l'ajouter à la liste d'utilisateurs en ligne. Pour le moment, le serveur ne connaît pas encore le nom du client. Il assumera un nom pour cet utilisateur, # 1, et le serveur enverra le nom + / t + # 1 au client, quel est votre nom?
3 Lorsque le client reçoit ce message, il saura que le serveur demande quel est son nom, donc le client enverra le nom + / t + # 1 + _ + son propre nom au serveur, (mon nom est xxx)
4 Après avoir reçu ce message, le serveur recherche dans la liste d'utilisateurs actuellement en ligne sur la base du n ° 1 et remplace # 1 par le nom du client, afin que le serveur connaisse le nom du client.
5 Lorsque le client quittera, le serveur déclenchera l'événement OnClose et le serveur supprimera l'utilisateur actuel de la liste en ligne.
Utilisez des images pour dessiner quelque chose comme ça (mal dessiné, -_- !!)
Code
js
ws = new WebSocket (ws: // + location.host + / WebSocket / socketserver);
Connectez-vous au serveur
Java
protégé StreamInbound CreateEweBSocketInbound (String Arg0,
HttpservletRequest arg1) {
// Talage de méthode générée automatiquement de TODO
return new Chatwebsocket (utilisateurs);
}
Créez un chatwebsocket pour gérer cette demande et déclencher l'événement onopen de l'objet Chatwebsocket
@Outrepasser
Vide protégée sur open (wsoutBound Outbound) {
// this.connection = connexion;
this.userName = # + string.valueof (UserNumber);
UserNumber ++;
essayer {
String message = name + / t + this.userName;
Charbuffer Buffer = Charbuffer.Wrap (message);
this.getwsoutBound (). writeTextMessage (tampon);
} catch (ioexception e) {
// Bloc de capture généré automatiquement de TODO
e.printStackTrace ();
}
users.add (this);
}
En supposant un nom pour ce client, en envoyant le nom supposé du nom + / t + au client et en ajoutant le client à la liste des clients actuellement connectés
js
Fonction Managedata (données)
{
var vals = data.split (/ t);
var msgType = vals [0];
commutateur (msgtype)
{
Nom de cas:
var msg = vals [1];
var mes = name + / t + msg + _ + nom d'utilisateur;
Envoyer (MES);
casser;
// ………
}
}
Acceptez et traitez le message envoyé par le serveur et constatez que le serveur lui a demandé quel est son nom, il a donc envoyé le nom + / t + le nom supposé + _ + au serveur.
Java
public void OnMessage (Data String) {
String [] Val1 = data.split (// t);
if (val1 [0] .equals (nom))
{
String [] val2 = val1 [1] .split (_);
pour (chatwebsocket utilisateur: utilisateurs) {
if (user.userName.equals (val2 [0])) {
user.Username = Val2 [1];
}
}
}
// ………
}
Traiter et accepter le message envoyé par le client, et constater que le client a répondu à son nom, alors recherchez dans la liste des clients actuellement connectés en fonction du nom présumé supposé, et transformez le pseudonyme en vrai nom
js
fonction SendMessage ()
{
var autre autre = $ (# autre) .Val ();
var msg = msg / t + nom d'utilisateur + _ + autre Name + _ + $ (# message) .Val ();
envoyer (msg);
}
Le client initie une conversation avec une autre personne, et le format de message est: msg + son propre nom + _ + nom opposé + _ + message
Java
public void OnMessage (Data String) {
/// …………
else if (val1 [0] .equals (msg))
{
String [] val2 = val1 [1] .split (_);
pour (chatwebsocket utilisateur: utilisateurs) {
if (user.userName.equals (val2 [1])) {
essayer {
Charbuffer temp = Charbuffer.Wrap (données);
user.getWsoutBound (). WriteTextMessage (temp);
} catch (ioexception e) {
// Bloc de capture généré automatiquement de TODO
e.printStackTrace ();
}
}
}
}
/// …………
}
On constate que le message est envoyé par le client. Selon le nom de l'autre partie, recherchez dans la liste des clients actuellement connectés et envoyez-lui le message.
js
Fonction Managedata (données)
{
var vals = data.split (/ t);
var msgType = vals [0];
commutateur (msgtype)
{
///…
Case MSG:
var val2s = vals [1] .split (_);
var de = val2s [0];
var message = val2s [2];
alert (de +: + message);
casser;
défaut:
casser;
}
}
Il a été constaté que c'était un message envoyé par un autre client, et il était affiché par alerte
Java
@Outrepasser
protégé void onclose (int status) {
Users.Remove (this);
}
Découvrir le client est parti, supprimer le client de la liste des clients connectés
Où s'améliorer
1. Si le client A envoie un message à B et B n'est pas en ligne, le message peut être stocké dans la base de données. Lorsque B est constaté en ligne, il sera récupéré de la base de données et envoyé à B.
2 Lorsque le serveur envoie votre nom, il peut ajouter un mécanisme de délai d'expiration. Si le client ne répond pas à son appel dans un certain délai, le client peut supprimer le client de la liste en ligne.