Prefacio
HTML5 WebSocket implementa la comunicación bidireccional entre el servidor y el navegador. La comunicación bidireccional hace que el desarrollo del mensaje del servidor sea más simple. Los más comunes son la comunicación instantánea y las aplicaciones que requieren información real en tiempo real. La mayoría de los mensajes del servidor anteriores empujan las tecnologías de "votación" y "conexión larga", las cuales incurrirían en una sobrecarga considerable en el servidor, y el rendimiento en tiempo real no fue particularmente alto. La tecnología WebSocket solo incurrirá en una pequeña sobrecarga y es particularmente alta en tiempo real. Comencemos explicando cómo usar la tecnología WebSocket para desarrollar salas de chat. En este ejemplo, se utiliza el servidor TomCat7. Cada servidor tiene diferentes implementaciones de WebSocket, por lo que esta instancia solo se puede ejecutar en el servidor Tomcat. Sin embargo, Spring ha lanzado la API de WebSocket, que es compatible con la implementación de cada servidor. Puede consultar la información relevante para comprender. No lo presentaré aquí. La siguiente imagen es la representación de la sala de chat:
En este ejemplo, se implementa el impulso en tiempo real de los mensajes, y también se implementan notificaciones en línea y fuera de línea de los usuarios de chat. Comencemos explicando en detalle cómo implementarlo.
Procesamiento de back -end
Tomcat implementa principalmente WebSocket confiando en la clase org.apache.catalina.websocket.messageInbound. Esta clase está en {tomcat_home} /lib/catalina.jar, por lo que cuando se desarrolla, debe presentar Catalina.jar y Tomcat-Coyote.jar. El siguiente código está expuesto a la dirección de servlet del cliente:
paquete com.ibcio; import javax.servlet.annotation.webservlet; import javax.servlet.http.httpservletRequest; importar org.apache.catalina.websocket.streaminbound; @WebServlet (urlPatterns = {"/mensaje"}) // Si desea recibir solicitudes del protocolo ws: // del navegador, debe implementar la clase de WebSocketServlet de la clase pública WebSocketMessageServlet extiende org.apache.catalina.websocket.websocketServlet {serialversionUid final de larga duración final de larga duración de larga resistente = 1L; public static int en línea_user_count = 1; Public String getUser (httpservletrequest request) {return (string) request.getSession (). getAttribute ("User"); } // A diferencia de los servlets ordinarios, se debe implementar CreateWebSocketInbound, y el objeto de conexión WebSocket personalizado se inicializa aquí @Override StreamInBound CreateWeSBoebocketInBound (String Subprotocol, HttPservletRequest Solicitud) {devuelve el nuevo WebSocketMessageInbound (this.getuser (solicitud)); }} Este servlet es algo diferente de los servlets ordinarios. Hereda la clase WebSocketServlet y necesita anular el método CreateWebSocketInbound. El atributo de usuario en sesión en esta clase se establece cuando el usuario ingresa index.jsp y registra el apodo del usuario actual. El siguiente es el código de la clase WebSocketMessageInbound implementado por usted mismo:
paquete com.ibcio; import java.io.ioException; import java.nio.bytebuffer; import java.nio.charbuffer; importar net.sf.json.jsonObject; importar org.apache.catalina.websocket.messageInbound; importar org.apache.catalina.websocket.wsoutBound; Public Class WebSocketMessageInbound extiende MessageInbound {// El nombre de usuario de la conexión actual es un usuario privado de cadena final; public WebSocketMessageInBound (String User) {this.user = user; } public String getUser () {return this.user; } // Evento activado estableciendo una conexión @Override protegida void onopen (wsoutbound outbound) {// activar el evento de conexión y agregar la conexión en el grupo de conexión jsonObject resultado = new jsonObject (); result.element ("type", "user_Join"); result.element ("usuario", this.user); // Presione el mensaje de que el usuario actual está en línea a todos los usuarios en línea WebSocketMessageInboundpool.sendMessage (result.toString ()); resultado = new JsonObject (); result.element ("type", "get_online_user"); result.element ("List", WebSocketMessageInboundpool.getOnlineUser ()); // Agregue el objeto de conexión actual al grupo de conexión WebSocketMessageInboundpool.addMessageInbound (esto); // Envía la lista de usuarios en línea actual a la conexión actual WebSocketMessageInBoundpool.SendMessageTouser (this.user, result.toString ()); } @Override protegido void onClose (int status) {// activar el evento de cierre y eliminar la conexión del grupo de conexión websocketMessageInboundpool.RemoVemessageInbound (esto); JsonObject resultado = new JsonObject (); result.element ("type", "user_leeve"); result.element ("usuario", this.user); // Envía el mensaje al usuario en línea que el usuario actual sale de WebSocketMessageInboundpool.sendMessage (result.toString ()); } @Override protegido nulo OnbinaryMessage (Mensaje ByteBuffer) arroja ioexception {tirar nueva no apoyoperationException ("Mensaje binario no admitido"); } // El evento se activa cuando el cliente envía un mensaje al servidor @Override void onTextMessage (Charbuffer Message) lanza ioexception {// Envía un mensaje a todos los usuarios en línea WebSocketMessageInboundpool.sendMessage (Message.ToString ()); }} El código implementa principalmente métodos Onopen, OnClose y OnTextMessage, que manejan los mensajes en línea, fuera de línea y envían mensajes de los usuarios respectivamente. Hay una clase WebSocketMessageInboundpool Connection Pool en esta clase. Esta clase se utiliza para administrar las conexiones de los usuarios actualmente en línea. El siguiente es el código de esta clase:
paquete com.ibcio; import java.io.ioException; import java.nio.charbuffer; import java.util.hashmap; import java.util.map; import java.util.set; clase pública WebSocketMessageInBoundpool {// Guardar el contenedor de mapa para la conexión Mapa final estático privado <String, WebSocketMessageInBound> Connections = new Hashmap <String, WebSocketMessageInBound> (); // Agregue una conexión al grupo de conexión Public static void addMessageInBound (WebSocketMessageInbound inbound) {// Agregar conexión System.out.println ("User:" + inBound.getUser () + "Join .."); Connectss.put (inbound.getuser (), entrbound); } // Obtenga todos los usuarios en línea Public static set <String> getOnlineUser () {return Connections.KeySet (); } public static void removeMessageInbound (WebSocketMessageInbound entrante) {// eliminar la conexión System.out.println ("User:" + inBound.getuser () + "Salir .."); Connectss.remove (inbound.getuser ()); } public static void sendMessageToUser (String User, String Mensaje) {try {// Enviar datos a usuarios específicos System.out.println ("Enviar mensaje al usuario:" + Usuario + ", Mensaje Contenido:" + Mensaje); WebSocketMessageInbound inBound = Connections.get (usuario); if (inBound! = null) {inBound.getWSoutBound (). WriteTextMessage (charbuffer.wrap (mensaje)); }} catch (ioException e) {E.PrintStackTrace (); }} // Enviar un mensaje a todos los usuarios publicidad estática void sendMessage (mensaje de cadena) {try {set <string> keySet = conections.KeySet (); for (clave de cadena: keySet) {WebSocketMessageInbound inBound = conections.get (key); if (inBound! = null) {System.out.println ("Enviar mensaje al usuario:" + Key + ", Mensaje Contenido:" + Mensaje); inbound.getwSoutBound (). WriteTextMessage (charbuffer.wrap (mensaje)); }}} Catch (ioException e) {E.PrintStackTrace (); }}} Pantalla de recepción
El código anterior es el código del backend de la sala de chat, que se compone principalmente de 3 objetos, servlet, objeto de conexión y grupo de conexión. El siguiente es el código de la recepción. El código de la recepción implementa principalmente conexión con el servidor y muestra la lista de usuarios y la lista de información. La visualización de la recepción utiliza el marco EXT. Los estudiantes que no están familiarizados con EXT pueden tener una comprensión preliminar de Ext. El siguiente es el código de index.jsp:
<%@ page lenguaje = "java" pageEncoding = "utf-8" import = "com.ibcio.websocketMessageServlet"%> <%string user = (string) session.getAttribute ("user"); if (user == null) {// Genere un apodo para el usuario user = "invitado" + WebSocketMessageServlet.Online_User_count; WebSocketMessageServlet.Online_USer_Count ++; session.SetAttribute ("Usuario", usuario); } pageContext.SetAttribute ("usuario", usuario); %> <html> <fead> <title> sala de chat de WebSocket </title> <!-Introducir archivos CSS-> <link rel = "stylesheet" type = "text/css" href = "ext4/recursos/css/ext-todos rel = "stylesheet" type = "text/css" href = "css/webSocket.css"/> <!- El paquete JS de desarrollo JS de Input Ext y su propio WebScoket implementado. -> <script type = "text/javascript" src = "ext4/ext-all-debug.js"> </scritch> <script type = "text/javascript" src = "websock.js"> </script> <script type = "text/javascript"> var user = "$ {user}"; </script> </head> <body> <h1>WebSocket Chat Room</h1> <p>The API provided by the HTML5 standard is combined with the Ext rich client framework to implement the chat room, which has the following characteristics: </p> <ul style="padding-left: 10px;"> <li>Retrieve data in real time, push it by the server, realizing instant communication</li> <li>Use WebSocket to complete data communication, que es diferente de las tecnologías como la encuesta y la conexión larga, y guarda los recursos del servidor </li> <li> Combinado con Ext para pantalla de página </li> <li> Notificación de usuario en línea y fuera de línea </li> </ul> <div ID = "WebSocket_Button"> </div> </body> </html> La visualización de la página se controla principalmente en WebSocket.js. El siguiente es el código de WebSocket.jsd:
// Used to display the user's chat information Ext.define('MessageContainer', { extend : 'Ext.view.View', trackOver : true, multiSelect : false, itemCls : 'l-im-message', itemSelector : 'div.l-im-message', overItemCls : 'l-im-message-over', selectedItemCls : 'l-im-message-selected', style : {Overflow: 'Auto', BackgroundColor: '#fff'}, tpl: ['<Viv> No confíe en las remesas, la información ganadora o las llamadas telefónicas no familiarizadas durante la conversación. '<div>{content}</div>', '</div>', '</tpl>'], messages : [], initComponent : function() { var me = this; me.messageModel = Ext.define('Leetop.im.MessageModel', { extend : 'Ext.data.Model', fields : ['from', 'timestamp', 'content', 'fuente']}); Mensaje ['Timestamp'] = ext.Date.Format (nueva fecha (Mensaje ['Timestamp']), 'H: I: S'); if (message.from == user) {Message.Source = 'Self'; } else {message.source = 'remoto'; } me.store.add (mensaje); if (me.el.dom) {me.el.dom.scrolltop = me.el.dom.scrollheight; }}}); Este código implementa principalmente el contenedor que muestra el mensaje. El siguiente es el código que comienza a ejecutar después de cargar la página:
Ext.onReady(function() { //Create the user input box var input = Ext.create('Ext.form.field.HtmlEditor', { region : 'south', height : 120, enableFont : false, enableSourceEdit : false, enableAlignments : false, listeners : { initialize : function() { Ext.EventManager.on(me.input.getDoc(), { keyup : function(e) {if (E.CtrlKey === True && E.KeyCode == 13) {E.PreventDefault (); Ext.create ('ext.panel.panel', {región: 'centro', diseño: 'border', elementos: [entrada, salida], botones: [{text: 'send', handler: send}]}); WebSocket (codeuri ('ws: // localhost: 8080/webSocket/message')); } webSocket.Onclose = function () {// Conexión desconectada win.settitle (title + '(desconectado)'); } // Recepción de mensajes websocket.onmessage = function (mensaje) {var message = json.parse (message.data); // Recibir mensajes enviados por el usuario if (message.type == 'Message') {output.Receive (Mensaje); } else if (message.type == 'get_online_user') {// Obtener lista de usuarios en línea var root = onlineUser.getRootNode (); Ext.each (Message.list, function (usuario) {var nodo = root.createnode ({id: user, text: user, icOncls: 'user', hoja: true}); root.appendchild (nodo);}); } else if (message.type == 'user_join') {// El usuario se pone en línea var root = onlineUser.getRootNode (); VAR user = Message.user; var nodo = root.createnode ({id: user, text: user, icOncls: 'user', hoja: true}); root.appendChild (nodo); } else if (message.type == 'user_leave') {// El usuario no se desconectó var root = onlineUser.getRootNode (); VAR user = Message.user; var nodo = root.findchild ('id', usuario); root.removechild (nodo); }}}}}; //Online User Tree var onlineUser = Ext.create('Ext.tree.Panel', { title : 'Online', rootVisible : false, region : 'east', width : 150, lines : false, useArrows : true, autoScroll : true, split : true, iconCls : 'user-online', store : Ext.create('Ext.data.TreeStore', { root : { text : 'Online Usuario ', expandido: verdadero, niños: []}})}); VAR Title = 'Bienvenido:' + Usuario; // Ventana de visualización var win = ext.create ('ext.window.window', {title: title + '(no conectado)', diseño: 'border', iconcls: 'user-win', minwidth: 650, minHeight: 460, ancho: 650, animatetectampet: 'websocket_button', altura: 460, ítems: ítems: ítems: [Dialog: border, border, borderget: : {render: function () {initWebSocket (); win.show (); // Enviar función de mensaje send () {var Message = {}; if (webSocket! = null) {if (input.getValue ()) {ext.apply (mensaje, {desde: user, content: input.getValue (), timestamp: new Date (). getTime (), type: 'Message'}); websocket.send (json.stringify (mensaje)); //output.receive(message); input.setValue (''); }} else {ext.msg.alert ('tip', '¡Ha sido desconectado y no puede enviar mensajes!'); }}}});El código anterior es el código que se conecta automáticamente al servidor después de cargar la página y crea la interfaz de visualización.
Aviso
Dos puntos a tener en cuenta: después de que se complete el despliegue, Catalina.jar y Tomcat-Coyote.jar en el directorio LIB en el directorio de solicitudes Tomcat deben eliminarse. Por ejemplo, el directorio LIB del proyecto es D:/Workspace/WebSocket/Webroot/Web-Inf/Lib, y el directorio Lib de aplicación implementado es D: /tools/apache-Tomcat-7.0.32/webapps/websocket/webinf/lib. Simplemente elimine el directorio LIB del directorio de implementación y conecta dos frascos. De lo contrario, el error puede no ser inicializado. Recordar.
Si la conexión aún no es posible, descargue el último Tomcat. Olvidé que la versión de TomCatCreateWebSocketInbound no tiene un parámetro de solicitud. El código actual tiene este parámetro. Las versiones 7.0.3xx vienen con este parámetro, recuerde.
Resumir
El uso de WebSocket para desarrollar el empuje del servidor es muy conveniente. Esta es una aplicación simple. De hecho, también puede combinar WEBRTC para realizar chat de video y chat de voz.
Descarga de ejemplo
Dirección de descarga: demostración
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.