jueves, 5 de marzo de 2020

Chat Privado con NodeJs parte 5 ( Creando estilo a ventana privada ) Final.

Continuando con el proyecto del chat privado con node js, es momento de finalizar, de antemano les agradezco el prestarme su tiempo para leerme y continuar con el proyecto, entrada tras entrada.


Comencemos, Es hora de dar fin al proyecto concluyendo con el estilo a la ventana privada de nuestro chat, para ello, nos vamos a nuestro archivo chatstyle.css agregando los siguientes estilos.

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;
}
.conv-privada {
    border: solid 1px #a0a0a0;
    width: 300px;
    position: absolute;
    left: 300px;
    background-color: #fafafa;
}
.cnt-title {
    padding: 0.5em;
    background-color: #2f2f5d;
    color: white;
    cursor: move;
}
.cnt-conv {
    height: 250px;
    overflow: hidden;
    background-color: #f7f4f4;
    overflow-y: scroll;
    margin-bottom: 0.25em;
}
.cntControl {
    border-top: solid 1px;
}
.conv {
    list-style: none;
    padding: 0.15em;
}
.conv li {
    margin: 0.15em;
    padding: 0.5em;
}

.msg-amigo {
    background-color: #bfbaf7;
}

.msg-propio {
    text-align: right;
    background-color: #a9c9e4;
}
.msg-amigo div, .msg-propio div {
    word-break: break-all;
}
.msg-propio span, .msg-amigo span {
    font-size: 0.75em;
}
.conv-close {
    position: absolute;
    right: 0.75em;
    font-style: initial;
    cursor: pointer;
    font-size: 1.25em;
    top: 0.25em;
}
.conv-finalizada {
    height: 26.15em;
    width: -webkit-fill-available;
    background: #3e3e3e5c;
    position: absolute;
    top: 2em;
}


Hagamos un resumen de lo expuesto.

La estructura del proyecto deberá haber quedado de la siguiente manera.


El archivo chatstyle.css quedará como lo muestro anteriormente, ahora, control.js queda de la siguiente manera:

Control.js

var socket = io();
var btnLogin = document.getElementById('btnLogin');
var lg = document.getElementById('login');
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;
 }
}
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; i0){
   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);
 }
});
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;
}
function draggable_2(title, content) {
    var px = 0, py = 0;
    var dragObj = null;
    var obj = content || title;
    obj.style.position = "absolute";
    title.addEventListener('mousedown', function () {
        obj.addEventListener('mousedown', onMouseDown);
        function onMouseDown(a) {
            px = a.layerX;
            py = a.layerY;
            dragObj = obj;
        }
        obj.addEventListener('mouseup', function (e) {
            obj.removeEventListener('mousedown', onMouseDown, false);
            dragObj = null;
        });
        obj.addEventListener('mousemove', function (e) {
            var x = e.pageX - px;
            var y = e.pageY - py;
            if (dragObj == null)
                return;
            dragObj.style.left = x + "px";
            dragObj.style.top = y + "px";
        });
    });
}
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)};
 }
}
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);
}
draggable_2(document.getElementById('ttlUsersActivos'), document.getElementById('cntUsersActivos'));


El lado del cliente, es decir el index, debera quedar de la siguiente manera.

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>
          <div class="login" id="login">
               <input type="text" id="user" placeholder="UserName"><button id="btnLogin">Aceptar</button>
          </div>
          <div class="contentUser" id="cntUsersActivos" hidden>
               <div class="title-users" id="ttlUsersActivos">Usuarios Activos</div>
               <ul id="usersActivos"></ul>
          </div>
          <script type="text/javascript" src="/js/control.js"></script>
     </body>
</html>





y por ultimo el app.js queda de la siguiente manera.

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");
var users = [];
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){
 socket.on('disconnect',function(){
  var keys =  Object.keys(users);
  var existe = false;
  var disconnected = {};
  for( var i = 0;i < keys.length; i ++ ){
   if( users[keys[i]] == socket.id ){
    disconnected.user = keys[i];
    disconnected.clave = users[keys[i]];
    delete users[keys[i]];
    existe = true;
   }
  }
  if(disconnected.hasOwnProperty('user')){
   io.emit('isDisconnected',disconnected);
  }
  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);
 });
 socket.on('send_message',function(data){
  var socketId = users[data.recibe];
  io.to(socketId).emit("newMessage",data);
 });
 socket.on('imWriting',function(dta){
  var socketId = users[dta.recibe];
  io.to(socketId).emit("isWriting",dta);
 });
});
http.listen(8420,function(){
 console.log('listening');
});



Anterior

Sin mas por el momento, me despido... Te invito a dejar tu comentario, que te parecio el tutorial, si quieres que le agregemos algo mas, o si tienes sugerencias al respecto.


Saludos, hasta la proxima.


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.

martes, 28 de enero de 2020

JMenuBar en java

Un menú siempre es necesario en nuestras aplicaciones ya que nos permiten seleccionar e ir directo a una tarea en particular que realiza nuestra aplicación, en este caso agregar el menubar a nuestra aplicación puede resultar bastante sencillo.


Para ello requerimos de las importaciones de javax.swing.JMenuBar, JMenu, y JMenuItem, correspondientemente.

Sin mas vamos al grano.



--
//clase Menu, para mostrar la implementaicon de un menu 

import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

/**
 *
 * @author oscar martagon
 */
public class Menu extends JApplet{
    JFrame f;
    public void createFrame(){
        f=new JFrame("Inovania.blogspot.com");
        f.setSize(400,400);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        createMenu();
    }
    public void createMenu(){
        JMenu menuPadre = new JMenu("Inicio");
        JMenuItem nuevo = new JMenuItem("Nuevo");
        menuPadre.add(nuevo);
        menuPadre.add(new JMenuItem("Salir"));
        
        JMenuBar mb = new JMenuBar();
        mb.add(menuPadre);
        f.setJMenuBar(mb);
    }
    public static void main(String[] args) {
        Menu m = new Menu();
        m.createFrame();
    }
}


--

Explicando el codigo...

Como ya lo explique en la entrada anterior JFrame en este caso se agrega el método createMenu() en el cual se agrega la linea.

JMenu menuPadre = new JMenu("Inicio");

Nos permite crear el nodo del cual saldran los diferentes submenus o menus items, Con la linea

JMenuItem nuevo = new JMenuItem("Nuevo");
menuPadre.add(nuevo);

Construimos un menu item con el texto de Nuevo y posteriormente se agrega al menuPadre, tambien se puede agregar un submenu o menuItem directamente al menu padre como se ve en la siguiente linea.

menuPadre.add( new JMenuItem("Salir");

Por ultimo se construye el Menu Bar al cual se agrega el menu padre y posteriormente se setea al frame con las lineas.

JMenuBar mb = new JMenuBar();
mb.add( menuPadre );
f.setJMenuBar( mb );

Por el momento es todo, espero te sea de ayuda, posteriormente veremos como agregar eventos al menu.

Espero tus comentarios, nos vemos pronto.

JFrame en java

Hola a todos, espero me tengan algo de paciencia, pues este sera el comienzo de una idea que tengo, tratar de explicar con ejemplos la mayoría de los elementos que componen a java swing comenzando por un lienzo para pintarlos, JFrame.



El JFrame, es un elemento que nos permite agregar en el diversos componentes dejando por un lado la consola de java dando paso al entorno visual o UI de java.

Sin mas vamos al comienzo.




--
//Manejo de JFrame en java

import javax.swing.JFrame;

/**
 *
 * @author oscar martagon
 */
public class Frame extends JFrame{
    public Frame(){
        JFrame f = new JFrame("Inovania.blogspot.com");
        f.setSize(400,400);
        f.setVisible(true);
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public static void main(String[] args) {
        Frame app = new Frame();
    }
}

--
Lo que estamos haciendo en el código anterior es construir un JFrame con el titulo del blog.

JFrame f = new JFrame("Inovania.blogspot.com");

Un tamaño de 400 por 400.

f.setSize(400,400);

Mostrándolo en el centro de la pantalla.

f.setLocationRelativeTo(null);

Por ultimo agregamos el evento de cierre de la ventana al dar click en la "x" de cierre.

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Cosas que se pueden agregar al JFrame.

Desabilitar el botón de maximizar, para ello solo agregamos la linea.

f.setResizable(false);

Inicializar el JFrame de manera minimizada en la barra de inicio.

f.setExtendedState(1);

Espero les ayude en algo este código, continuare con los demas elementos de JavaSwing mostrando con ejemplos prácticos para su uso... espero sus comentarios y visitas.

hasta la proxima.

jueves, 23 de enero de 2020

Metodo de Ordenamiento en java

Los métodos de ordenamiento nos ayudan a visualizar de manera mas clara un arreglo o lista, ya sea que se requiera de manera ascendente o descendente, en java encontramos tres métodos bastantes conocidos comencemos por el mas básico.

Ordenamiento de burbuja.

Su nombre es básicamente por la manera en como trabaja el algoritmo de ordenamiento ya que se trata de tomar el peso de cada elemento y dejar que de esta manera se vaya pasando hasta que quede ordenado.

El código es el siguiente.

public int[] bubbleSort(int[] n){
   int tmp;
   int t = n.length;
   for( int i = 1; i < t; i ++ ){
        for( int k = t-1; k >= i; k --){
            if( n[k]<n[k-1]){
               tmp=n[k];
               n[k]=n[k-1];
               n[k-1]=tmp;
            }
        }
   }
   return n;
}

La invocacion sera la siguiente
int[] arrInt = {5,6,9,12,48,356,4,1,0,1574};
int[] rtnNumber = bubbleSort(arrInt);
dando como salida
run:
5,6,9,12,48,356,4,1,0,1574
0,1,4,5,6,9,12,48,356,1574
BUILD SUCCESSFUL (total time: 0 seconds)

Como les comentaba hace un momento existen otros dos métodos de ordenamiento muy conocidos entre ellos esta el llamado QickSort:

Basado en la tecnica Divide y Venceras, toma un elemento del arreglo (pivote) dejando los menores a el de un lado mientras que del otro lado los mayores a este. segementando el arreglo hasta que este quede ordenado.

El código es el siguiente.

---
    public void Quicksort(int[] vector, int first, int last) {
        int i = first, j = last;
        int pivote = vector[(first + last) / 2];
        int auxiliar;
        do {
            while (vector[i] < pivote) {
                i++;
            }
            while (vector[j] > pivote) {
                j--;
            }
            if (i <= j) {
                auxiliar = vector[j];
                vector[j] = vector[i];
                vector[i] = auxiliar;
                i++;
                j--;
            }
        } while (i <= j);

        if (first < j) {
            Quicksort(vector, first, j);
        }

        if (last > i) {
            Quicksort(vector, i, last);
        }
    }

---
El llamado sera el siguiente

int[] arr = {6, 5, 1, 3, 8, 4, 9, 7, 12, 45, 16, 83, 128, 0, 45};
Quicksort(arr, 0, arr.length - 1);

Dejando como salida el siguiente resultado
run:
6,5,1,3,8,4,9,7,12,45,16,83,128,0,45,
0,1,3,4,5,6,7,8,9,12,16,45,45,83,128,
BUILD SUCCESSFUL (total time: 0 seconds)


Ya por ultimo tenemos el siguiente método de ordenamiento HeapSort.

Este método se desarrolla de manera recursiva, no estable, consiste en almacenar todo el arreglo o elementos dentro de un vecotr a ordenar formando algo similar a un monticulo, llevando los menores de un lado y pasandolos  de derecha a izquierda en una estructura de tipo arbol.

El codigo es el siguiente

---
    public void fnSortHeap(int arr[], int arr2) {
        int i, o;
        int lCh, rCh, mCh, root, tmp;
        root = (arr2 - 1) / 2;
        for (o = root; o >= 0; o--) {
            for (i = root; i >= 0; i--) {
                lCh = (2 * i) + 1;
                rCh = (2 * i) + 2;
                if ((lCh <= arr2) && (rCh <= arr2)) {
                    if (arr[rCh] >= arr[lCh]) {
                        mCh = rCh;
                    } else {
                        mCh = lCh;
                    }
                } else {
                    if (rCh > arr2) {
                        mCh = lCh;
                    } else {
                        mCh = rCh;
                    }
                }

                if (arr[i] < arr[mCh]) {
                    tmp = arr[i];
                    arr[i] = arr[mCh];
                    arr[mCh] = tmp;
                }
            }
        }
        tmp = arr[0];
        arr[0] = arr[arr2];
        arr[arr2] = tmp;
    }




---
Quedando el llamado de la siguiente manera

int arr[] = {6, 5, 1, 3, 8, 4, 9, 7, 12, 45, 16, 83, 128, 0, 45};
for (i = arr.length; i > 1; i--) {
      app.fnSortHeap(arr, i - 1);
}

Dejando como salida el siguiente resultado
run:
---------------
6,5,1,3,8,4,9,7,12,45,16,83,128,0,45
0,1,3,4,5,6,7,8,9,12,16,45,45,83,128
---------------
BUILD SUCCESSFUL (total time: 0 seconds)

Sin mas por el momento espero esto les aya servido de ayuda en algo, de ser así me gustaria saber de tu experiencia con estos métodos, comparte con tus amigos este blog y no olvides seguirme para estar al día con las siguientes entradas.

martes, 21 de enero de 2020

Expresiones regulares en java

Las expresiones regulares nos ayudan a buscar desde un numero, signo, palabra o segmentar una cadena según sea el caso.

En javascript, php, python o java, el como invocar una expresión puede variar dependiendo del lenguaje, en este caso hablaremos solo de java.


Comenzando con nuestra clase ExpresionRegular

public class ExpresionRegular{

    public static void main(String[] args) {
    }
}

String cadena = "Lorem ips43um dolor sit amet, conse2342ctetur adipisicing elit. Suscipit voluptatum at ape459/*-5riam voluptas tenetur temporibus vero q321uisquam 23laudantium sint debitis, veniam reprehenderit consequu132ntur autem aut aspernatur? Dolores aperiam praesentium ad.";

De la cadena lorem ipsum la modificaremos tantito. ahora buscaremos solo las palabras que contengan números, con la siguiente expresión.

/*Create by Inovania.blogspot.com*/
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ExpresionRegular{

    public static void main(String[] args) {
     String cadena = "Lorem ips43um dolor sit amet, conse2342ctetur adipisicing elit. Suscipit voluptatum at ape459/*-5riam voluptas tenetur temporibus vero q321uisquam 23laudantium sint debitis, veniam reprehenderit consequu132ntur autem aut aspernatur? Dolores aperiam praesentium ad.";
     Pattern p = Pattern.compile("([a-z]+[0-9]+[a-z]+)" );
     Matcher m = p.matcher(cadena);

        while( m.find() ){
            System.out.println( m.group() );
        }
    }
}

Dandonos como resultado lo siguiente.

ips43um
conse2342ctetur
q321uisquam
consequu132ntur

Dejando así las palabras que contengan letras + numeros + letras ignorando el resto.


Sin mas por el momento me despido como siempre , quedando en espera de sus comentarios, dudas o sugerencias.

No olvides recomendarme.
hasta pronto.

miércoles, 15 de enero de 2020

Buscar texto en archivos desde cmd

Recientemente me encuentro con la siguiente tarea. buscar la palabra "x-palabra" todos los archivos con extensión "x-extensión" por lo que me di a la tarea de navegar en linea para saber si ya existe un método que pueda ayudarme a hacer dicha tarea.

Lo primer que se me ocurrio fue hacer algo en java ya que es el lenguaje que mejor se manejar, sin embargo para correrlo y hacer que dicho programa funcione son varios pasos a seguir, programas extras que abrir, en fin, actualmente me encuentro trabajando con windows y se me ocurrio hacer dicha busqueda en un archivo con extencion .bat ya que para ejecutar este tipo de archivos solo se necesita habrir una consola o bien seleccionar el archivo dandole doble click. 

En fin, esto fue por lo que pase para cumplir con mi objetivo.

Buscar como esta estructurado un archivo .bat,
buscar como se ejecutan sus funciones.
como recorrer un directorio
como buscar un texto dentro de un directorio
como pasar una variable dentro de una funcion en un batch 
como guardar la información en un txt-File

Una vez concluido la busqueda y tras haber hecho varios ejemplos llegue a cumplir mi objetivo, dejando el archivo.bat de la siguiente manera.

::create by inovania.blogspot.com
@echo off
cls
:inicio
call :existeArchivo "salida.txt"
set/p b = directorio:
set frace="palabraABuscar"
echo %b%
echo *************************************
for /r %b% %%a in (*.extension*) do (
    find %frace% %%a >> salida.txt
)
echo finalizando
echo *************************************
goto fin
:existeArchivo
echo archivos donde se esta buscando la palabra %frace% > %~1
:fin

explicando


Comienza limpiando el contenido de lapantalla.
cls

:inicio
call :existeArchivo "nombre.extension"
nos permite invocar la funcion existeArchivo pasandole como parametro el nombre del archivo con la extencion correspondiente.


set/p b=directorio:
esta linea nos permite agregarle el directorio donde queremos que busque

set frace="frace a buscar"
se guarda en una variable la frace que se quiere buscar dentro de cada archivo

for  /r   %b%   %%a   in   (*.extension*) do find  %frace% %%a  >> salida.txt
esta linea nos permite buscar a partir del directorio guardado en la variable %b% todos los archivos con la extension seleccionada la la palabra almacenada en la variable %frace% guardando el resultado del comando find en el archivo salida.txt

goto fin
se mueve a la funcion fin la cual finaliza el proceso y libera la consola para otra ejecucion por parte del usuaurio.


:existeArchivo
echo archivos donde se esta buscando la palabra %frace% > %~1

construye el archivo que se recibe como parametro %~1 en la funcion guardandolo con la primera linea que se esta poniendo en echo

dejando una respuesta en el archivo de la siguiente manera


De esta manera nos devuelve como resultado todos los archivos donde busco el texto y en el archivo que exista una o mas coincidencia aparecera como se muestra en la imagen...


espero les aya servido de algo,
si te agrado deja tu comentario,
si tienes cuenta de google unete de esta manera seras de los primeros en tener mis entradas.


sin mas por el momento. hasta pronto.

lunes, 13 de enero de 2020

Como hacer una Intranet usando el Celular como Modem

Asi como lo leen, ni mas ni menos que en esta entrada les mostrare como hacer una red local de manera muy sencilla usando un celular como modem,


Lo que necesitamos es lo siguiente, un par de smartphone, una computadora (puede ser de escritorio, de preferencia una laptop ) y listo.


Pasos a seguir. toma tu smartphone el mejor que tengas y dale compartir internet, para ello te vas a la opcion -->configuracion y redes-->zona wi-fi y conexiones, activas la opcion-->zona wi-fi portatil.

Nota. si solo quieres hacer una red local desactivar los datos moviles.


Esta opcion te dara un nombre de red y una contraseña la cual tendras que asignar a los dispositivos que quieres conectar a tu red, y listo.


Demasiado sencillo cierto.


Tips. si quieres agregar una computadora de escritorio, es necesario conectar el celular que estas usando como modem a dicha computadora. y al momento de conectarlo mediante tu cable usb. seleccionas la opcion compartir internet por cable usb. De esta manera estaras agregando a tu red interna la computadora de escritorio.

de esta manera si tienes agregado xampp, glassFish o algun otro servidor de aplicaciones web que tengas puedes levantarlo en tu maquina y todos los dispositivos que se conecten a dicha red podran verla de manera natural en su navegador.


Bueno sin mas por el momento los dejo hasta aquí en espera de sus comentarios. de antemano gracias por leerme

MouseEvent en jTable

Es tiempo de comenzar a agregarle eventos a nuestra tabla.

Continuando con el proyecto de creación de un JTabla en java, es hora de agregar un par de eventos a nuestra tabla, como es el evento de MouseListener y sus métodos, correspondientes.

Por el momento solo aremos que al seleccionar una celda esta nos devuelva todo el renglón completo.

Para ver los diversos métodos que tiene el mouse sobre nuestra tabla pueden encontrarlo en la entrada eventos del mouse.

Siguiendo, agregamos un metodo llamado eventos el cual lo invocamos desde nuestro constructor o metodo init(), dentro de este metodo le agregaremos a nuestra tabla el evento MouseListener dentro del cual nos quedara de la siguiente manera.

    private void eventos() {
        tabla.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) {}

        });
    }

En el cual estaremos trabajando en el primer evento mouseClicked, indicando el renglon que se ah seleccionado con tabla.getSelectedRow() obtenemos un objeto de getDataVector().elementAt()
el cual (en mi caso ) lo convertimos en un string separado por (,) y listo, tenemos el contenido de nuestro registro para lo que se necesite.


el codigo les tendra que quedar de la siguiente manera

public void mouseClicked(MouseEvent e) {
   int row = tabla.getSelectedRow();
   Object elm = dtm.getDataVector().elementAt( row );
    String es = ( elm.toString() ).substring(1, ( elm.toString().length() -1 ));
    String[] a = es.split(",");
    for( String b: a ){
        System.out.println( b.trim() );
    }
}

Dejando el resultado de la siguiente manera




bueno amigos es todo por el momento. espero les sirva de apoyo esto si tienen alguna duda, dejen su comentario, leere todos y cada uno de ellos dando respuesta a lo que se pueda.