Prefácio
O WebSocket HTML5 implementa a comunicação bidirecional entre servidor e navegador. A comunicação bidirecional simplifica o desenvolvimento da mensagem do servidor. Os mais comuns são comunicação instantânea e aplicativos que exigem informações de alta qualidade em tempo real. A maior parte da mensagem anterior do servidor empurra as tecnologias de "pesquisa" e "conexão longa" usadas, ambas incorrentes de sobrecarga considerável no servidor, e o desempenho em tempo real não foi particularmente alto. A tecnologia WebSocket apenas incorrerá pequena e é particularmente alta em tempo real. Vamos começar explicando como usar a tecnologia WebSocket para desenvolver salas de bate -papo. Neste exemplo, o servidor TomCat7 é usado. Cada servidor possui implementações diferentes do WebSocket, portanto, esta instância só pode ser executada no servidor Tomcat. No entanto, a Spring lançou a API do WebSocket, que é compatível com a implementação de cada servidor. Você pode consultar as informações relevantes para entender. Eu não vou apresentá -lo aqui. A imagem a seguir é a renderização da sala de bate -papo:
Neste exemplo, o impulso em tempo real das mensagens é implementado e as notificações on-line e offline dos usuários de bate-papo também são implementadas. Vamos começar a explicar em detalhes como implementá -lo.
Processamento de back -end
O Tomcat implementa principalmente o WebSocket, confiando na classe org.apache.catalina.websocket.messageInbound. Esta classe está em {tomcat_home} /lib/catalina.jar; portanto, quando você se desenvolver, você precisa apresentar catalina.jar e tomcat-coyote.jar. O código a seguir é exposto ao endereço do servlet do cliente:
pacote com.ibcio; importar javax.servlet.annotation.webServlet; importar javax.servlet.http.httpServletRequest; importar org.apache.catalina.webSocket.streamInbound; @WebServlet (urlpatterns = {"/message"}) // Se desejar receber solicitações do protocolo ws: // do navegador, você deve implementar a classe websocketSertlet classe public websocketmessageServletttends stands staftalina. public static int online_user_count = 1; public string getUser (httpServletRequest request) {return (string) request.getSession (). getAttribute ("user"); } // Diferentemente dos servlets comuns, o createWebocketInbound precisa ser implementado, e o objeto de conexão Websocket personalizado é inicializado aqui @Override ProtectedInBound CreateWeBsocketInBound (String Subprotocol, httpServletRequest Solicy) {Return websocketMessageInBound (this.getUSer (Solicy); }} Este servlet é um pouco diferente dos servlets comuns. Ele herda a classe WebSocketServlet e precisa substituir o método CreateWebocketInbound. O atributo do usuário na sessão nesta classe está definido quando o usuário insere index.jsp e registra o apelido do usuário atual. A seguir, é apresentado o código da classe WebSocketMessageInbound implementada por você:
pacote com.ibcio; importar java.io.ioException; importar java.nio.byteBuffer; importar java.nio.charbuffer; importação net.sf.json.jsonObject; importar org.apache.catalina.websocket.messageInbound; importar org.apache.catalina.websocket.wsoutbound; classe pública websocketmessageInbound estende MessageInbound {// O nome de usuário da conexão atual é o usuário da String final privada; public webSocketMessageInBound (String User) {this.User = user; } public string getUser () {return this.User; } // Evento acionado estabelecendo uma conexão @Override Protected Void Onopen (WSOUTBOUND OUTBOUND) {// aciona o evento de conexão e adicione a conexão no pool de conexão JsonObject Result = new JsonObject (); resultado.Element ("tipo", "user_join"); resultado.Element ("Usuário", this.User); // Pressione a mensagem de que o usuário atual está online a todos os usuários on -line webSocketMessageInboundpool.sendMessage (resultado.toString ()); resultado = new jsonObject (); resultado.Element ("tipo", "get_online_user"); Result.Element ("List", WebSocketMessageInboundpool.getonLineUser ()); // Adicione o objeto de conexão atual ao pool de conexão websocketmessageInboundpool.addmessageInbound (this); // Envie a lista de usuários on -line atual para a conexão atual WebSocketMessageInboundpool.sendMessageTouser (this.User, resultado.toString ()); } @Override Protected void onclose (int status) {// aciona o evento de fechamento e remova a conexão do pool de conexão websocketmessageInboundpool.RemoveMessageInBound (this); Resultado jsonObject = new jsonObject (); resultado.Element ("tipo", "user_leave"); resultado.Element ("Usuário", this.User); // Envie a mensagem para o usuário on -line de que o usuário atual sai do websocketMessageInboundpool.sendMessage (resultado.toString ()); } @Override Protected void onbinaryMessage (mensagem de bytebuffer) lança ioexception {lança novo UnsupportEdOperationException ("mensagem binária não suportada"); } // O evento é acionado quando o cliente envia uma mensagem para o servidor @Override Protected void otextMessage (mensagem CharBuffer) lança ioexception {// Enviar mensagem para todos os usuários on -line websocketmessageInboundpool.sendMessage (message.tostring ()); }} O código implementa principalmente os métodos ONOPEN, ONCLOSE e ONTEXTMESSAGE, que lidam com os usuários on -line, offline e enviam mensagens, respectivamente. Existe uma classe WebSocketMessageInBoundPool Conexão nesta classe. Esta aula é usada para gerenciar as conexões dos usuários atualmente on -line. A seguir, o código desta classe:
pacote com.ibcio; importar java.io.ioException; importar java.nio.charbuffer; importar java.util.hashmap; importar java.util.map; importar java.util.set; classe pública websocketmessageInboundpool {// Salvar o contêiner do mapa para conexão MAPATIVO ESTÁTICO PRIVADO PRIVADO <String, WebSocketMessageInbound> Connections = new Hashmap <String, WebsocketMessageInbound> (); // Adicione uma conexão ao pool de conexão public static void addMessageInbound (websocketMessageInbound inbound) {// Adicione o conexão System.out.println ("user:" + inbound.getUser () + "junção .."); conexão.put (inbound.getUser (), entrada); } // Obtenha todos os usuários on -line Public Static Set <String> getOnlineUser () {return ConnectionS.KeySet (); } public static void removeMessageInbound (webSocketMessageInbound inbound) {// Remover conexão System.out.println ("Usuário:" + inbound.getUser () + "Exit .."); conexion.remove (inbound.getUser ()); } public static void sendMessageTouser (Usuário da String, Mensagem String) {Try {// Envie dados para usuários específicos System.out.println ("Envie a mensagem para o usuário:" + User + ", Mensagem Content:" + Mensagem); WebSocketMessageInbound inbound = conexão.get (usuário); if (inbound! = null) {inbound.getwsoutBound (). writeTextMessage (charbuffer.wrap (mensagem)); }} catch (ioexception e) {e.printStackTrace (); }} // Envie uma mensagem para todos os usuários public static void sendMessage (string message) {try {Set <String> keySet = conexão.KeySet (); para (String Key: Keyset) {webSocketMessageInbound inbound = ConnectionS.get (key); if (inbound! = null) {System.out.println ("Envie a mensagem para o usuário:" + key + ", conteúdo da mensagem:" + mensagem); inbound.getWsOutBound (). writeTextMessage (charbuffer.wrap (mensagem)); }}} catch (ioexception e) {e.printStackTrace (); }}} Exibição da recepção
O código acima é o código do back -end da sala de bate -papo, que é composto principalmente por 3 objetos, servlet, objeto de conexão e pool de conexão. A seguir, o código da recepção. O código da recepção implementa principalmente a conexão com o servidor e exibe a lista de usuários e a lista de informações. A exibição da recepção usa a estrutura ext. Os alunos que não estão familiarizados com EXT podem ter um entendimento preliminar do ext. A seguir, o código do index.jsp:
<%@ Page Language = "Java" PageEncoding = "UTF-8" import = "com.ibcio.webSocketMessageServlet"%> <%string user = (string) session.getAttribute ("user"); if (user == null) {// gerar um apelido para o usuário user = "convidado" + websocketmessageservlet.online_user_count; WebSocketMessageServlet.online_user_count ++; session.setAttribute ("Usuário", usuário); } PageContext.SetAttribute ("Usuário", usuário); %> <html> <head> <title> WebSocket Chat Room </ititle> <!-Apresente arquivos CSS-> <link rel = "Stylesheet" type = "text/css" href = "ext4/resources/css/ext-all.css"> <link rel = "styleset" e "type = ".. rel = "Stylesheet" type = "text/css" href = "css/websocket.css"/> <!- Entrar o pacote de desenvolvimento JS da EXT EXT e seu próprio WebsCoket implementado. -> <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 = "$ {{}} {Usery}; </script> </ad Head> <body> <h1> WebSocket Chat Room </h1> <p> A API fornecida pelo padrão HTML5 é combinada com a estrutura do cliente rica rica para implementar a sala de bate-papo, que tem as seguintes características: </p> <l style = padding-left: 10px; Comunicação, que é diferente de tecnologias como pesquisa e conexão longa, e salva recursos do servidor </li> <li> Combinado com Ext for Page Exibir </li> <li> Usuário online e notificação offline </li> </ul> <div id = "websocket_button"> </div> </body> </html> A exibição da página é controlada principalmente em websocket.js. A seguir, o código do 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: ['<div> Não confie em remessas, ganhando informações ou chamadas telefônicas desconhecidas durante a conversa. '<div> {content} </div>', '</div>', '</tpl>'], mensagens: [], initComponent: function () {var Me = this; 'fonte']}); mensagem ['timestamp'] = ext.date.format (nova data (mensagem ['timestamp']), 'h: i: s'); if (message.from == user) {message.source = 'self'; } else {message.source = 'remoto'; } me.store.add (mensagem); if (me.el.dom) {me.el.dom.scrolltop = me.el.dom.scrolHeight; }}}); Este código implementa principalmente o contêiner que exibe a mensagem. A seguir, é apresentado o código que começa a executar após o carregamento da 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 : função (e) {se Ext.Create ('Ext.Panel.Panel', {Region: 'Center', Layout: 'Border', itens: [entrada, saída], botões: [{Text: 'Send', manipulador: send}]}}); WebSocket (Encodeuri ('ws: // localhost: 8080/websocket/message'); } websocket.onclose = function () {// conexão desconectada win.settitle (title + '(desconectada)'); } // Recepção de mensagem websocket.onmessage = function (message) {var message = json.parse (message.data); // Receba mensagens enviadas pelo usuário if (message.type == 'message') {output.receive (message); } else if (message.type == 'get_online_user') {// obtenha a lista de usuários on -line var root = onlineUser.GetRootNode (); Ext.each (message.list, function (user) {var node = root.creatEnode ({id: user, texto: usuário, iconCls: 'user', folha: true}); root.appendChild (node);}); } else if (message.type == 'user_join') {// o usuário passa on -line var root = onlineUser.getRootNode (); var user = message.User; var node = root.creatEnode ({id: usuário, texto: usuário, iconCls: 'user', folha: true}); root.appendChild (nó); } else if (message.type == 'user_leave') {// o usuário sai offline var root = onlineUser.getRootNode (); var user = message.User; var node = root.findChild ('id', usuário); root.RemoVechild (nó); }}}}}; //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 Usuário ', Expandido: True, filhos: []}})}); var title = 'Bem -vindo:' + usuário; // janela de exibição var win = ext.create ('ext.window.window', {title: title + '(não conectado)', layout: 'border', iconCls: 'user-win', minwidth: 650, minhEight: 460, largura: 650, itens: 'websocket_button', altura: 460, largura: 650, animateTarget: 'websocket_button', render: function () {initwebSocket (); win.show (); // Enviar função da mensagem send () {var message = {}; if (webSocket! = null) {if (input.getValue ()) {ext.apply (mensagem, {de: user, content: input.getValue (), timestamp: new date (). gettime (), tipo: 'mensagem'}); webSocket.send (json.stringify (mensagem)); //output.Receive(Message); input.setValue (''); }} else {ext.msg.alert ('tip', 'você foi desconectado e não pode enviar mensagens!'); }}}});O código acima é o código que se conecta automaticamente ao servidor depois que a página é carregada e cria a interface de exibição.
Perceber
Dois pontos a serem observados: após a conclusão da implantação, Catalina.Jar e Tomcat-Coyote.jar no diretório Lib no diretório de aplicativos Tomcat precisam ser excluídos. Por exemplo, o diretório Lib do projeto é d:/workspace/websocket/webroot/web-inf/lib, e o diretório LIB do aplicativo implantado é d: /tools/apache-tomcat-7.0.32/webapps/websocket/web-b-sp-g-fssment/lib. Basta excluir o diretório Lib do diretório de implantação e conectar dois frascos. Caso contrário, o erro não pode ser inicializado. Lembrar.
Se a conexão ainda não for possível, faça o download do último tomcat. Esqueceu que a versão do tomcatcreatewebelbound não possui um parâmetro de solicitação. O código atual possui esse parâmetro. As versões 7.0.3xx vêm com este parâmetro, lembre -se.
Resumir
O uso do WebSocket para desenvolver o push do servidor é muito conveniente. Este é um aplicativo simples. De fato, ele também pode combinar o WebRTC para realizar bate -papo por vídeo e bate -papo por voz.
Exemplo de download
Endereço para download: demonstração
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.