miércoles, 26 de febrero de 2020

Chat Privado con NodeJs parte 4 ( Creación de ventana privada )

En chat privado con NodeJs.

Como les comente en la entrada anterior, vimos como generar la lista de usuarios y mandarla a las ventanas ( usuarios ) conectados.

Creando la venta privada.


Ahora veremos como hacer la ventana de conversación privada a manera que valla quedando de la siguiente manera...

Por ahora comenzaremos con los siguientes cambios.

app.js

//
 socket.on('send_message',function(data){
  var socketId = users[data.recibe];
  io.to(socketId).emit("newMessage",data);
 });

Este código trata de lo siguiente, obtenemos de dta -> el usuario quien va a recibir el mensaje, extraemos el socket.id de la lista de usuarios  y reenviamos dta directo a la función newMessage, por otro lado en control.js estaremos haciendo muchos mas cambios.

Comenzando por el echo de agregar la siguiente linea a la función isLogin.

control.js

   liUser.onclick=newConversacion;

newConversacion:


Se encarga de invocar la función armaVentanaPrivada la cual construirá lo necesario para que se tenga una conversación privada con cierto usuario.

control.js

function newConversacion(e){
 var to = e.target.innerText;
 var clave = e.target.getAttribute('clave');
 armaVentanaPrivada(clave, to);
}

function armaVentanaPrivada(clave,to){
 if(document.getElementById(clave)==null){
  var cnt = create({type:'DIV','id':clave,class:'conv-privada'});
  var emClose = create({type:'EM',class:'conv-close'});
  var ttl = create({type:'DIV',class:'cnt-title'});
  var cntCnv = create({type:'DIV',class:'cnt-conv','id':'cntCnv_'+clave});
  var lista = create({type:'UL',class:'conv','id':'conv_'+clave});
  var cntCtr = create({type:'DIV',class:'cntControl'});
  var notificacion = create({type:'DIV',class:'is-writing',id:'isW_'+clave});
  var txtMsg = create({type:'TEXTAREA',name:'entrada',rows:'4','id':'inpMsg_'+clave,'style':'resize:none;width:225px;'});
  var btn = create({type:'BUTTON','id':'btn_'+clave,'style':'float: right;padding: 0.7em;margin-top: 0em;padding-top: 1.5em;padding-bottom: 2em;position: absolute;'});
  ttl.textContent=to;
  btn.textContent="Aceptar";
  emClose.textContent='X';
  cntCtr.appendChild(txtMsg);
  cntCtr.appendChild(btn);
  cntCnv.appendChild(lista);
  ttl.appendChild(emClose);
  cnt.appendChild(ttl);
  cnt.appendChild(cntCnv);
  cnt.appendChild(notificacion);
  cnt.appendChild(cntCtr);
  document.body.appendChild(cnt);
  draggable_2(ttl,cnt);
  txtMsg.onkeyup=function(){
   socket.emit('imWriting',{
    user:window.datos.user,
    clave:window.datos.clave,
    length: this.value.length,
    recibe:to
   });
  }
  emClose.onclick = function(){
  cnt.remove();
 }
 btn.onclick = function(){
  if((txtMsg.value.trim()).length>0){
   socket.emit('send_message',{
    recibe:to,
    envia:{user:window.datos.user,clave:window.datos.clave},
    message:txtMsg.value
   });
   agregaMensaje(lista,1,window.datos.user,txtMsg.value, cntCnv);
   txtMsg.value = '';
   txtMsg.focus();
  }
 }
 return {lista:lista,content:cntCnv};
}else{
 return {lista:document.getElementById('conv_'+clave), content: document.getElementById('cntCnv_'+clave)};
}
}
                
Para esta función le pasaremos dos parámetros, clave la cual es el socket.id de quien esta enviando el mensaje o bien a quien se va a enviar el mensaje y como segundo parámetro es el nombre del usuario. La acción de esta función, es bastante básica.
  • Pregunta si ya existe una conversación para la clave que se está pasando como parámetro
    • de ser así retornará un objeto de dos propiedades, { lista: el objeto de lista de conversación, content: el objeto contenedor de la conversación } 
  • Si no existe la conversación con la clave que se esta pasando, se construirá la ventana flotante.
    • Ahora bien, al botón se agrega el evento click, el cual va a extraer el contenido del text área y se enviara a la función send_message pasando le un objeto con las propiedades, 
    • {
      • recibe: el id del socket a quien queremos enviar el mensaje,
      • envia: { 
        • user: usuario que está enviando el mensaje, 
        • clave: clave del usuario que envia el mensaje 
        • }, 
      • message: el contenido del textarea 
    • }
  • Ahora bien. A la caja de texto se agrega el evento keyup el cual siempre y cuando el value de esta caja sea mayor a 1 en ese caso se envía una petición a la función imWriting pasando como parámetro un objeto con las características.
    • {
      • user: usuario que envía,
      • clave: clave del usuario que envía,
      • length: longitud de texto escrito,
      • recibe: id de usuario que recibirá la notificación
    • }
  • De esta manera el usuario con quien se esta conversando sabrá que se esta escribiendo su respuesta a  su comentario.

Debido a que del lado del servidor tenemos un reenvio del mensaje, o bien, recibiendo el mensaje de alguien, es necesario hacer la función newMessage quedando de la siguiente manera.

control.js

//
socket.on('newMessage',function(value){
 var obj = armaVentanaPrivada(value.envia.clave,value.envia.user);
 agregaMensaje(obj.lista,2,value.envia.user,value.message,obj.content);
 var ntf = document.getElementById('isW_'+value.envia.clave);
 ntf.textContent='';
});


Como pueden ver en la función armaVentanaPrivada se invoca una función llamada create, bueno esta funcion esta construida de la manera que sirve para poder hacer los elementos del dom pasando solo las propiedades del elemento, 

control.js

//
function create(dta){
 var obj = Object.keys(dta);
 var elemento = document.createElement(dta.type);
 for( var i = 0; i < obj.length; i ++ ){
  if(obj[i]!='type'){
   elemento.setAttribute(obj[i],dta[obj[i]]);
  }
 }
 return elemento;
}

Para concluir me quedan un par de funciones que agregar, en este caso las funciones que muestran cuando el usuario con quien estamos hablando esta escribiendo o bien cuando el usuario con quien estamos hablando se desconecta.

control.js

socket.on('isWriting',function(dta){
 if(document.getElementById(dta.clave)!=null){
  var ntf = document.getElementById('isW_'+dta.clave);
  if(dta.length>0){
   ntf.textContent=dta.user+" is writing...";
  }else{
   ntf.textContent='';
  }
 }
});
socket.on('isDisconnected',function(dta){
 if(document.getElementById(dta.clave)!=null){
  var ntf = document.getElementById('isW_'+dta.clave);
  ntf.textContent=dta.user+" is disconnected";
  var block = create({type:'DIV',class:'conv-finalizada'});
  var cnt = document.getElementById(dta.clave);
  cnt.appendChild(block);
 }
});


Se me estaba olvidando una de las funciones mas importantes del tema, el agregar el mensaje a nuestra conversación, quedando de la siguiente manera.

control.js

function agregaMensaje(ul,cve,de,msg,cntCnv){
 var dvm = create({type:'DIV'});
 var li = create({type:'LI',class:((cve==1)?'msg-propio':'msg-amigo')});
 var spn = create({type:'SPAN'});
 var fd = new Date();
 var time = fd.getHours()+":"+fd.getMinutes()+":"+fd.getSeconds();
 spn.textContent= ((cve==1)?time+" "+de:de+" "+time);
 dvm.textContent= msg;
 li.appendChild(spn);
 li.appendChild(dvm);
 ul.appendChild(li);
 cntCnv.scrollTo(0,cntCnv.scrollHeight);
}

Sin mas por el momento me despido, esperando que me dejen sus comentarios, que tal les ha parecido el tutorial hasta ahora, si quienren que se agrege algo mas o si me pase de algo....


No olvides hacerte un seguidor y estar al pendiente de la proxima entrada en la cual mostraremos como hacer el estilo a la ventana privada.


hasta pronto.

Anterior                                                                                     Siguiente

lunes, 24 de febrero de 2020

Chat Privado con NodeJs parte 3 ( Estilo a lista de usuarios )

Continuando con el tema del chat es momento de embellecer nuestra lista de usuarios.

Es el momento de crear y modificar el archivo  chatStyle.css en la carpeta raíz/css/chatstyle.css, para ello, lo creamos y comenzamos a agregar los estilos a las diferentes clases.

chatstyle.css

body {
    font: 13px Helvetica, Arial;
}
.contentUser {
    border: solid 1px;
    width: 300px;
    position: absolute;
    top: 10px;
    left: 10px;
    border-radius: 5px;
    height: 500px;
}
ul#usersActivos {
    list-style: none;
    padding: 0;
    height: 445px;
    overflow: hidden;
    overflow-y: scroll;
}
.title-users {
    padding: 1em;
    background-color: #2f2f5d;
    text-align: center;
    color: #f1f1f1;
    cursor: move;
}
#usersActivos li {
    border-bottom: solid 1px;
    padding: 0.75em;
    cursor: pointer;
}
#usersActivos li div {
    font-size: 1.15em;
}


Esto dejara una lista de usuarios con el siguiente estilo

Y es así como concluimos esta entrada... 



Esperare sus comentarios, si no se han unido al blog, agrégalo como favorito. 




Chat privado con nodeJs Parte. 2 ( Conexion y registro de usuarios )

Historia:


Continuando con el proyecto de chat privado con nodeJs ahora veremos como hacer los métodos del lado del servidor.

Desde este lado nos encargaremos de hacer que los clientes se conecten entre si poniendo un intermediario a la conversación.

En este caso los archivos a modificar son, index.html, app.js y control.js, agregando las siguientes lineas.

Código:


index.html
<!-- pantalla login -->
   <div class="login" id="login">
      <input type="text" id="user" placeholder="UserName">
      <button id="btnLogin">Aceptar</button>
   </div>
<!-- plantilla de usuarios -->
   <div class="contentUser" id="cntUsersActivos" hidden>
        <div class="title-users" id="ttlUsersActivos">Usuarios Activos</div>
        <ul id="usersActivos"></ul>
   </div>

Este fragmento se va directo al body del index, dando pie a un input el cual contendra el usuario y un boton que mandara la petición al app.js para asignar un nombre al socket que se acaba de conectar. La acción la agregamos al.

control.js

var btnLogin = document.getElementById('btnLogin');
btnLogin.onclick=function(){
 var usr = document.getElementById('user');
 if((usr.value.trim()).length>0){
  socket.emit('connectUser',usr.value);
  window.datos={
   user:usr.value,
   clave: socket.id
  };
  window.document.title = usr.value;
 }
}


Obtenemos el elemento btnLogin y le asignamos la función click, mediante la cual le decimos que obtenga del input su valor y lo mande a la función ('conectUser') que se encuentra en app.js ademas de crear una variable global en window llamada [" datos "] con los parametros user y clave, por ultimo se cambia el titulo de la ventana dandole el nombre del usuario que se a conectado.

Ademas de agregar el evento click al botón, hay que agregar la función de la recepción de usuarios del lado del cliente, es decir, la parte que agrega usuarios a nuestra lista.

control.js

var lg = document.getElementById('login');
socket.on('isLogin',function(value){
 if(typeof window.datos != 'undefined'){
  lg.setAttribute('hidden','');
  var userActivos = document.getElementById('usersActivos');
  userActivos.parentNode.removeAttribute('hidden');
  userActivos.innerHTML = "";
  for(var i = 0; i<value.length; i ++ ){
   if(value[i].clave!=window.datos.clave){
    var liUser = document.createElement('LI');
    var divUser = document.createElement('DIV');
    divUser.textContent=value[i].user;
    divUser.setAttribute('clave',value[i].clave);
    liUser.setAttribute('clave',value[i].clave);
    liUser.appendChild(divUser);
    userActivos.appendChild(liUser);
   }
  }
 }
});


socket.on( 'isLogin') se encarga de escuchar del lado del cliente, las emisiones del servidor, app.js, en este caso leemos cada uno de los usuarios agregandolos o eliminandolos de nuestra lista.

Ahora bien, del lado del app es necesario explicar lo siguiente. crearemos un arreglo llamado users en el cual se agrega el usuario que se acaba de conectar, modificando la funcion de disconnect, preguntamos por el id que se esta desconectando, para asi eliminar el usuario correspondiente del lado del cliente.

app.js

var users = [];
io.on('connection',function(socket){
 socket.on('disconnect',function(){
  var keys =  Object.keys(users);
  var existe = false;
  for( var i = 0;i < keys.length; i ++ ){
   if( users[keys[i]] == socket.id ){
    delete users[keys[i]];
    existe = true;
   }
  }
  if(existe){
   var nKeys = Object.keys(users);
   var arrRtn = [];
   for( var i = 0;i < nKeys.length; i ++ ){
    arrRtn.push({'user':nKeys[i], 'clave': users[nKeys[i]]});
   }
   io.emit('isLogin',arrRtn);
  }
 });
 socket.on('connectUser',function(user){
  var existe = false;
  var keys =  Object.keys(users);
  var arrRtn=[];
  for( var i = 0;i < keys.length; i ++ ){
   arrRtn.push({'user':keys[i], 'clave': users[keys[i]]});
   if( users[keys[i]] == socket.id ){
    existe = true;
   }
  }
  if(!existe){
   users[user]=socket.id;
   arrRtn.push({'user':user, 'clave': socket.id});
  }
  io.emit('isLogin',arrRtn);
 });
});


Agregamos la función connectUser pasando como parámetro al usuario recién conectado, primero preguntamos si el usuario nuevo existe, de ser así no se hace nada, de lo contrario si no existe se agrega al arreglo y finalmente se envía al cliente en el arreglo de usuarios.




Por ahora es todo, espero sus comentarios.

Unete a mi blog, para asi poder estar al tanto de la siguiente entrada.



Anterior             Siguiente

domingo, 23 de febrero de 2020

Chat privado con NodeJS

Historia:


Anteriormente les deje una entrada con el tema Principios con NodeJs en el cual les hablo de como iniciar un proyecto de hola mundo con node js.

Bueno ahora les traigo un proyecto con la idea de hacer un chat privado, bastante básico y sencillo de hacer.

Sin mas comenzamos.

Instalacion:


Primero que nada comencemos con la instalacion de node js la cual es muy sencilla, bajamos el instalador correspondiente a nuestro sistema en mi caso es windows de 64 bits.

Link: https://nodejs.org/es/download/



La instalación es bastante sencilla como cualquier programa, Instalar-> siguiente -> siguiente 
->siguiente -> finalizar, una vez instalado lo que sigue es la construcción de nuestro proyecto, en xampp\htdocs creamos una carpeta la cual sera nuestro chat. para ello seguimos los siguientes pasos...

Configuracion:



   C:\xampp\htdocs>mkdir inovaniachat

una vez creada la carpeta inicializamos el proyecto,

     npm init


instalamos express y socket.io

        npm install express@4.15.2
        npm install socket.io


con ello tenemos todo lo necesario para continuar con nuestro proyecto, lo que sigue es hacer el index.html y nuestra app.js  quedando con el siguiente codigo.

Código:


index.html

<!DOCTYPE html>
<html lang="en">
<head>
     <meta charset="UTF-8">
     <title>inovania</title>
          <script type="text/javascript" src="/socket.io/socket.io.js"></script>
          <link rel="stylesheet" type="text/css" href="/css/chatstyle.css">
     </head>
     <body>
          <script type="text/javascript" src="/js/control.js"></script>
     </body>
</html>



control.js

var socket = io();


app.js

var express = require("express");
var app = express();
var http = require("http").createServer(app);
var io = require("socket.io")(http);
var path = require("path");

app.get('/',function(req,res){
 res.sendFile(__dirname+"/pages/index.html");
});
var publicDir = path.join(__dirname,'/');
app.use(express.static(publicDir));

io.on('connection',function(socket){
 console.log('user is connected');
 socket.on('disconnect',function(){
  console.log('user is disconnected');
 });
});
http.listen(8420,function(){
 console.log('listening');
});


Les dejo aquí un vídeo de referencia.

Sin mas por el momento los espero en la próxima entrada.



Deja tu comentario, si tienes cuenta de google, hazte un seguidor de inovania para que te lleguen las notificaciones de los siguientes post.

Siguiente

martes, 4 de febrero de 2020

Diferencia entre ActionListener, keyListener, MouseListener y focusListener in java

Los eventos action listener, son eventos que se agregan a los diferentes componentes de java, no se confundan con los eventos de mouseListener o keyListener, ya que dichos eventos corresponden a diferentes acciones del usuario.

Un ActionListener, se produce al hacer click sobre el componente, o bien al dar enter siempre y cuando el componente tenga el foco.
--
/*actionListener*/
JMenuItem item = new JMenuItem("salir");
item.addActionCommand("salir");
item.addActionListener(this);

@Override
public void actionPerformed(ActionEvent e ){
   if( e.getActionCommand()=="salir" ){
      JOptionPane.showMessageDialog(null,"Adios");
      System.exit(0);
   }
}

--
Un KeyListener, se ejecuta al precionar una tecla, dependiendo el momento de su ejecucion cambara de metodo interno, tales como
 * KeyTyped(keyEvent e) se ejecuta al presionar y soltar una tecla
 * KeyPressed( keyEvent e ) se ejecuta al presionar una tecla
 * KeyReleased( keyEvent e ) se ejecuta al soltar una tecla

--
        JTextField txt = new JTextField();
        txt.addKeyListener( new KeyListener(){
            @Override
            public void keyTyped(KeyEvent e) {
                System.out.println("keyTyped");
            }
            @Override
            public void keyPressed(KeyEvent e) {
                System.out.println("keyPressed");
            }
            @Override
            public void keyReleased(KeyEvent e) {
                System.out.println("keyReleased");
            }
        });

--

un focusListener, se ejecuta cuando un componente pierde o gana el foco ( es seleccionado o desseleccionado ). sus eventos son:
 * focusGained se ejecuta al recibir o perder el foco
 * focusLost se ejecuta al perder el foco

--
  
        JTextField txt = new JTextField();
        txt.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                System.out.println("FocusGained");
            }

            @Override
            public void focusLost(FocusEvent e) {
                System.out.println("focusLost");
            }
        });

--

Por ultimo tenemos mouseListener, que como su nombre lo dice, los eventos del mouse, estos eventos se relacionan a las acciones que se ejecutan directamente por el mouse, La descripcion de cada uno de ello lo pueden encontrar en la entrada MouseEvent donde se puedes encontrar mas a detalle el uso del mouseListener.

--
        JTextField txt = new JTextField();
        txt.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });


--

Sin mas por el momento es todo por hoy, dejen su comentario y nos leemos en la proxima.