Préface
HTML5 WebSocket implémente la communication bidirectionnelle entre le serveur et le navigateur. La communication bidirectionnelle facilite le développement du message du serveur. Les plus courantes sont la communication instantanée et les applications qui nécessitent des informations de haute qualité en temps réel. La plupart du message du serveur précédent pousse des technologies de "sondage" et de "longue connexion", qui entraîneraient toutes deux des frais généraux considérables sur le serveur, et les performances en temps réel n'étaient pas particulièrement élevées. La technologie WebSocket entraînera seulement de petites frais générales et est particulièrement élevée en temps réel. Commençons par expliquer comment utiliser la technologie WebSocket pour développer des salles de chat. Dans cet exemple, le serveur Tomcat7 est utilisé. Chaque serveur a des implémentations différentes de WebSocket, donc cette instance ne peut être exécutée que dans le serveur Tomcat. Cependant, Spring a lancé l'API WebSocket, qui est compatible avec l'implémentation de chaque serveur. Vous pouvez consulter les informations pertinentes à comprendre. Je ne le présenterai pas ici. L'image suivante est le rendu de la salle de chat:
Dans cet exemple, la poussée en temps réel des messages est implémentée et les notifications en ligne et hors ligne des utilisateurs de chat sont également implémentées. Commençons par expliquer en détail comment l'implémenter.
Traitement du backend
Tomcat implémente principalement WebSocket en s'appuyant sur la classe org.apache.catalina.websocket.MessageInbound. Cette classe est dans {tomcat_home} /lib/catalina.jar, donc lorsque vous développez, vous devez introduire Catalina.jar et Tomcat-Coyote.jar. Le code suivant est exposé à l'adresse du servlet du client:
package com.ibcio; Importer javax.servlet.annotation.webservlet; Importer javax.servlet.http.httpservletRequest; import org.apache.catalina.websocket.streaminbound; @Webservlet (urlpatterns = {"/ message"}) // Si vous souhaitez recevoir des demandes du protocole ws: // du navigateur, vous devez implémenter la classe WebSocketServlet de la classe publique WebSocketSageServlet étend org.apache.catalina.websocket.websocketServlet {privilège final sérialversionuid = 1L; public static int online_user_count = 1; Public String getUser (request httpServleRequest) {return (string) request.getSession (). getAtTribute ("utilisateur"); } // Contrairement aux servlets ordinaires, CreateWebSocketInbound doit être implémenté et l'objet de connexion WebSocket personnalisé est initialisé ici @Override Protected streaminbound CreateWeBSocketInbound (String SubprotoCol, httpServleRequest request); }} Ce servlet est quelque peu différent des servlets ordinaires. Il hérite de la classe WebSocketServlet et doit remplacer la méthode CreateWebSocketInbound. L'attribut utilisateur en session dans cette classe est défini lorsque l'utilisateur entre index.jsp et enregistre le surnom de l'utilisateur actuel. Ce qui suit est le code de la classe WebSocketMessageInbound implémentée par vous-même:
package com.ibcio; Importer java.io.ioException; import java.nio.bytebuffer; import java.nio.charbuffer; importer net.sf.json.jsonObject; import org.apache.catalina.websocket.MessageInbound; import org.apache.catalina.websocket.wsoutbound; classe publique WebSocketMessageInbound étend MessageInbound {// Le nom d'utilisateur de la connexion actuelle est un utilisateur de chaîne finale privée; public WebSocketMessageInbound (String User) {this.user = user; } public String getuser () {return this.user; } // Événement déclenché en établissant une connexion @Override Protected void onOpen (WSOutBound Outbound) {// déclenche l'événement de connexion et ajoutez la connexion dans le pool de connexion JSONObject result = new JSONObject (); result.element ("type", "user_join"); résultat.Element ("utilisateur", this.User); // appuyez sur le message selon lequel l'utilisateur actuel est en ligne à tous les utilisateurs en ligne WebSocketMessageInboundPool.SendMessage (result.toString ()); result = new JSONObject (); result.element ("type", "get_online_user"); result.element ("list", WebSocketMessageInboundPool.getOnLineUser ()); // Ajoutez l'objet de connexion actuel au pool de connexion WebSocketMessageInboundPool.AddMessageInbound (this); // Envoyez la liste d'utilisateurs en ligne actuelle à la connexion actuelle WebSocketMessageInboundPool.SendMessageSer (this.user, result.toString ()); } @Override Protected void onClose (int status) {// déclenchez l'événement de clôture et supprimez la connexion de la connexion WebSocketMessageInboundPool.RemoveMessageInbound (this); JsonObject result = new JSONObject (); result.element ("type", "user_leave"); résultat.Element ("utilisateur", this.User); // Envoyez le message à l'utilisateur en ligne que l'utilisateur actuel quitte WebSocketMessageInboundPool.SendMessage (result.toString ()); } @Override Protected void OnbinaryMessage (message ByteBuffer) lève IOException {Throw New UnsupportEperException ("Message binaire non pris en charge."); } // L'événement est déclenché lorsque le client envoie un message au serveur @Override Protected void onTextMessage (Charbuffer Message) lève ioException {// Envoyer un message à tous les utilisateurs en ligne WebSocketMessageInboundPool.SendMessage (message.tostring ()); }} Le code implémente principalement les méthodes Open, OnClose et OnTextMessage, qui gèrent respectivement des messages en ligne, hors ligne et envoient des messages. Il y a une classe de pool de connexion WebSocketMessageInboundPool dans cette classe. Cette classe est utilisée pour gérer les connexions des utilisateurs actuellement en ligne. Ce qui suit est le code de cette classe:
package com.ibcio; Importer java.io.ioException; import java.nio.charbuffer; import java.util.hashmap; importation java.util.map; import java.util.set; classe publique WebSocketMessageInboundPool {// Enregistrez le conteneur de carte pour connexion Private Static Final Map <String, WebSocketMessageInbound> Connections = new HashMap <String, WebSocketMessageInbound> (); // Ajouter une connexion au pool de connexion publique statique void addMessageInbound (WebSocketMessageInbound inbound) {// Ajouter une connexion System.out.println ("user:" + inbound.getUser () + "join .."); Connections.put (inbound.getUser (), inbound); } // Obtenez tous les utilisateurs en ligne public static set <string> getOnLineUser () {return Connections.KeySet (); } public static void removeMessageInbound (WebSocketMessageInbound inbound) {// supprimer le système de connexion.out.println ("utilisateur:" + inbound.getUser () + "exit .."); Connects.Remove (inbound.getUser ()); } public static void SendMessageSer (String User, String Message) {try {// Envoyer des données à des utilisateurs spécifiques System.out.println ("Envoyer le message à l'utilisateur:" + utilisateur + ", contenu du message:" + message); WebSocketMessageInbound inBound = Connections.get (utilisateur); if (inbound! = null) {inbound.getwsoutBound (). writeTextMessage (charbuffer.wrap (message)); }} catch (ioException e) {e.printStackTrace (); }} // Envoyez un message à tous les utilisateurs publics static void sendMessage (message de chaîne) {try {set <string> keyset = connections.KeySet (); for (String key: keySet) {WebSocketMessageInbound inBound = Connections.get (key); if (inbound! = null) {System.out.println ("Envoyer le message à l'utilisateur:" + key + ", contenu du message:" + message); inbound.getWsoutBound (). WriteTextMessage (charbuffer.wrap (message)); }}} catch (ioException e) {e.printStackTrace (); }}} Affichage de la réception
Le code ci-dessus est le code du backend de la salle de chat, qui est principalement composé de 3 objets, servlet, objet de connexion et pool de connexion. Ce qui suit est le code de la réception. Le code de la réception implémente principalement la connexion avec le serveur et affiche la liste des utilisateurs et la liste des informations. L'affichage de la réception utilise le cadre EXT. Les étudiants qui ne connaissent pas EXT peuvent avoir une compréhension préliminaire de l'EXT. Ce qui suit est le code d'index.jsp:
<% @ page Language = "Java" Pageencoding = "UTF-8" import = "com.ibcio.websocketMessageservlet"%> <% String user = (string) session.getAttribute ("user"); if (user == null) {// générer un surnom pour l'utilisateur utilisateur = "invité" + WebSocketMessageservlet.online_user_count; WebSocketMessageservlet.online_User_Count ++; session.setAttribute ("utilisateur", utilisateur); } pageContext.setAttribute ("utilisateur", utilisateur); %> <html> <éad- head> <itle> Websocket Chat Room </ title> <! - Introduire des fichiers CSS -> <link rel = "Stylesheet" type = "Text / CSS" href = "ext4 / ressources / css / ext-all.css"> <lin rel = "stylesheet" type = "text / css" href = "css / Websocket.css" /> <! - Le package de développement JS de l'entrée EXT et son propre WebScoket implémenté. -> <script type = "text / javascript" src = "ext4 / ext-all-debug.js"> </ script> <script type = "text / javascript" src = "Websocket.js"> </ script> <script type = "text / javascript"> var user = "$ {user}";; </criptring> </ head> <body> <h1> websocket Chat Room </h1> <p> L'API fournie par la norme HTML5 est combinée avec le cadre client riche pour implémenter la salle de chat, qui a les caractéristiques suivantes: </p> <ul style = "Padding-left-left: 10px;"> <li> Utiliser les données en temps réel, par le serveur, la communication réalisée, la communication réalisée, la communication réelle, La communication, qui est différente des technologies telles que le sondage et la longue connexion, et enregistre les ressources du serveur </li> <li> combinées avec EXT pour l'affichage de la page </li> <li> Utilisateur en ligne et la notification hors ligne </li> </ul> <div id = "Websocket_button"> </div> </body> </html> L'affichage de la page est principalement contrôlé dans WebSocket.js. Ce qui suit est le code de WebSocket.jsd:
// Utilisé pour afficher les informations de chat de l'utilisateur Ext.Define ('MessageContainer', {extension: 'ext.view.view', trackover: true, multiselect: false, itemcls: 'l-im-message', itelsselect Overflow: 'Auto', BackgroundColor: '#FFF'}, TPL: ['<div> Ne faites pas confiance aux envois de fonds, aux informations gagnantes ou aux appels téléphoniques inconnus pendant la conversation. '<div> {Content} </div>', '</div>', '</tpl>'], messages: [], initComponent: function () {var me = this; me.messagemodel = ext.efine ('leetop.im.messagemodel', {extension: 'extenne. 'Source']}); me.store = ext.create (ext.data.store ', {modèle:' leetop.im.messageModel ', data: me.messages}); Message ['TimeStamp'] = ext.date.format (nouvelle date (message ['Timestamp']), 'h: i: s'); if (message.from == user) {message.source = 'self'; } else {message.source = 'distant'; } me.store.add (message); if (me.el.dom) {me.el.dom.scrolltop = me.el.dom.scrollHeight; }}}); Ce code implémente principalement le conteneur qui affiche le message. Ce qui suit est le code qui commence à s'exécuter après le chargement de la page:
Ext.Onready (function () {// Créer la boîte d'entrée de l'utilisateur Var Input = ext.create ('ext.form.field.htmleditor', {région: 'South', hauteur: 120, activerfont: false, activepechet: false, actiatignments: false, les auditeurs: {initialize: function () {ext.eventManager.on (me.input.get.Getdd (). fonction (e) {if (e.ctrlkey === true && e.keycode == 13) {e.preventDefault (); Ext.create ('ext.panel.panel', {région: 'Centre', Layout: 'Border', items: [entrée, sortie], Buttons: [{Text: 'Send', Handler: Send}]}); WebSocket (encodeuri (ws: // localhost: 8080 / Websocket / message '); } Websocket.OnClose = function () {// connexion déconnectée win.settitle (title + '(déconnecté)'); } // réception de messages WebSocket.OnMessage = function (message) {var message = json.parse (message.data); // reçoit des messages envoyés par l'utilisateur if (message.type == 'message') {output.receive (message); } else if (message.type == 'get_online_user') {// get online utilisateur list var root = onlineUser.getRootNode (); Ext.each (message.list, fonction (utilisateur) {var node = root.createNode ({id: utilisateur, texte: utilisateur, iConcls: 'utilisateur', leaf: true}); root.appendChild (node);}); } else if (message.type == 'user_join') {// l'utilisateur va en ligne var root = onlineUser.getRootNode (); var user = message.User; var node = root.creenode ({id: utilisateur, texte: utilisateur, iconcls: 'utilisateur', leaf: true}); root.appendChild (nœud); } else if (message.type == 'user_leave') {// l'utilisateur se déconnecte hors ligne var root = onlineUser.getRootNode (); var user = message.User; var node = root.findchild ('id', utilisateur); root.removechild (nœud); }}}}}; // Tree utilisateur en ligne var onlineUser = ext.create ('ext. User ', étendu: true, enfants: []}})}); var title = 'bienvenue:' + utilisateur; // Afficher la fenêtre var win = ext.create ('ext.window.window', {Title: Title + '(non connecté)', Layout: 'Border', iCONCLS: 'User-win', Minwidth: 650, MinHeight: 460, Width: 650, AnimateTarget: 'Webocket_Button', Hight: 460 {render: function () {initwebsocket ();}}}); win.show (); // Envoi de la fonction de message Send () {var message = {}; if (WebSocket! = null) {if (input.getValue ()) {ext.apply (message, {from: user, contenu: input.getValue (), horodatamp: new date (). gettime (), type: 'message'}); WebSocket.Send (JSON.StRINGIFY (message)); //output.receive(Message); input.setValue (''); }} else {ext.msg.lert ('tip', 'vous avez été déconnecté et ne pouvez pas envoyer de messages!'); }}}});Le code ci-dessus est le code qui se connecte automatiquement au serveur après le chargement de la page et crée l'interface d'affichage.
Avis
Deux points à noter: une fois le déploiement terminé, Catalina.jar et Tomcat-Coyote.jar dans le répertoire Lib dans le répertoire de l'application Tomcat doivent être supprimés. Par exemple, le répertoire LIB du projet est d: / workspace / Websocket / webroot / web-inf / lib, et le répertoire LIB de l'application déployée est d: /tools/apache-tomcat-7.0.32/webapps/websocket/web-inf/lib. Supprimez simplement le répertoire LIB du répertoire de déploiement et connectez deux pots. Sinon, l'erreur peut ne pas être initialisée. Souviens-toi.
Si la connexion n'est toujours pas possible, veuillez télécharger le dernier Tomcat. J'ai oublié que la version de TomCatCreateWeBsocketInbound n'a pas de paramètre de demande. Le code actuel a ce paramètre. Les versions 7.0.3xx sont toutes livrées avec ce paramètre, n'oubliez pas.
Résumer
L'utilisation de WebSocket pour développer un push de serveur est très pratique. Il s'agit d'une application simple. En fait, il peut également combiner wEBRTC pour réaliser le chat vidéo et le chat vocal.
Exemple de téléchargement
Adresse de téléchargement: démo
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.