viernes, 18 de marzo de 2016

Simple Clock Control AJAX ASP

 Un problema común  en las páginas web es el asunto del hecho de dar la hora. Se puede hacer con javascript, pero daría la hora del lado Cliente, en algunos casos es probable que la computadora esté fuera de hora, generalmente porque son unos bagres y no le cambian la pila.
Supongamos que en nuestra aplicación empresarial (si es empresarial está demás decir que tiene que ser en ASP.Net) a veces necesito dar a conocer al usuario, qué hora tiene el Servidor.
 Esto se puede resolver directamente con ASP.Net sin hacer muchos malabares y simplemente usando Ajax y un UpdatePanel.
 Quiero suponer que cualquier persona que lleve 3 o 4 meses de experiencia en ASP.Net, ya tiene la librería Ajax Toolkit, que la puede descargar desde cualquier lado, incluso desde el mismo Visual Studio.
 Acá vamos a usar Visual Studio, el proyecto será un WebForm (No voy a usar MVC).

El WebForm tiene lo siguiente:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="ServerClock.WebForm1" %>

<%@ Register src="ServerClockControl.ascx" tagname="ServerClockControl" tagprefix="uc1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
 
        <uc1:ServerClockControl ID="ServerClockControl1" runat="server" />
 
    </div>
    </form>
</body>
</html>


Como verán, llamo al Control ServerClockControl que es el que tiene el reloj:
Ahora veamos que tiene adentro el ServerClockControl:


<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ServerClockControl.ascx.cs" Inherits="ServerClock.ServerClockControl" %>

<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <asp:Timer ID="TimerFecha" runat="server" Interval="2000" 
                ontick="TimerFecha_Tick">
            </asp:Timer>
            <asp:Timer ID="TimerHora" runat="server" Interval="1000" 
                ontick="TimerHora_Tick">
            </asp:Timer>
            <style type="text/css">
.txtAlign { TEXT-ALIGN: center }
</style>
            <p align="center" style="margin:1% 0;">
            
                <asp:Label ID="Label2" runat="server" Text="Date:"></asp:Label>
            
                </p>
            <p align="center" style="margin:-1% 0;" style="height: 20px">
                &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<asp:Label CssClass="txtAlign" ID="LabelFecha" runat="server" Text="12/12/2012 " 
                    BorderColor="#FF3300" BorderStyle="Outset" BorderWidth="1px"></asp:Label>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                </p>
                
                <p style="margin:1% 0;" align="center">
                <asp:Label ID="Label1" runat="server" Text="Time:"></asp:Label>
                </p>
                <p align="center" style="margin:-1% 0;" style="height: 20px">
                    
                <asp:Label CssClass="txtAlign" ID="LabelHora" runat="server" Text="--:--:--" 
                    style="height: 32px; " 
                    Font-Size="Larger" Font-Bold="True" BackColor="White" BorderColor="#FF3300" 
                        BorderWidth="2px" Height="35px" Width="92px"></asp:Label>
           
            </p>
            
            <br>
            <br>
            <br>
            <br>
        </ContentTemplate>
    </asp:UpdatePanel>


El ServerClockControl posee un UpdatePanel, la magia del UpdatePanel está en que todo lo que esté adentro, puede actualizarse con el Servidor sin necesidad de refrescar la página, el que  lo hace es AJAX, pero el UpdatePanel, es un control que simplifica el proceso.
Dentro del UpdatePanel está el <ContentTemplate> y dentro están dos controles Timer, uno actualiza la fecha y el otro la hora, uno está puesto para que actualice cada 2000 milisegundos y el otro cada 1000 milisegundos, osea 2 segundos y 1 segundo respectivamente. Podría haber sido solamente un Timer que actualice la fecha y la hora, pero se me ocurrió hacer 2 Timer y no tengo que andar explicando por qué, porque no tengo ganas.


Pero cómo es que actualiza la hora?
Bueno, eso le corresponde al código C# que está en ServerClockControl.ascx.cs
El método siguiente es el que se encarga de actualizar la fecha y la hora.
protected void TimerHora_Tick(object sender, EventArgs e)
{
 LabelHora.Text = DateTime.Now.ToString("hh:mm:ss");//ho.GetHora();

LabelFecha.Text = DateTime.Now.ToString("dd/MM/yyyy");// fe.GetFecha().Substring(0, 11);
}

Sí, tal cuál en Windows Form y en WPF, así, en LabelHora coloco el resultado de
DateTime.Now.ToString("hh:mm:ss"); en ese formato coloco hora, minutos y segundos, lo mismo va para la fecha, día, mes, año.
Finalmente queda así el control:

Gracias por leer!!! Yo soy Ger.
Bye!


Descarguen desde Codeplex, soy el usuario Becklespinax:
https://simpleajaxclockasp.codeplex.com/releases/view/101601

Proyecto en Codeplex:


domingo, 13 de marzo de 2016

MyIP (Programa para saber tu IP)

 Hola, un poco abandonado tengo el blog, hasta creo que le están saliendo tela de arañas...
 Este es el primer post de una serie de post que ya tengo casi escritos sobre programación.
 Acá va un artículo que escribí el año pasado y nunca publiqué, así que, disfruten... y si no lo disfrutan, me importa poco y nada.
Empecemos...
 Con el reciente cierre de GameSpy surgieron muchos inconvenientes a la hora de armar partidas on line de fórmula uno.
 El problema principal es que ya no pueden verse las partidas armadas, ese inconveniente planeo solucionarlo haciendo una web que muestre las partidas, pero por ahora no, en un futuro medio-lejano que quizás nunca llegue.
 Para armar partidas hay que usar algún sistema de redes como Hamachi, o en su defecto, quien arme una partida, debe pasarle la IP (Internet Protocol) de su conexión, así el que quiera unirse pueda hacerlo, pero surge aquí el inconveniente de los novatos: Cuál es mi IP?
 Cualquier usuario avanzado no duda mucho tiempo y enseguida lo obtiene yendo al panel de control de Windows o accediendo a múltiples páginas que se dedican a decirte cuál es tu IP.
Pero los usuarios novatos ni siquiera saben cuál es su IP, ni que es una IP, entonces decidí hacer este programita super simple en C# que les diga cuál es su IP en ese momento y tomo como base distintos métodos que he aplicado en  sistemas grandes que hice y que necesitaban saber la IP.

 Dividamos en 2 el trámite, por un lado está la IP Privada y por el otro, la IP pública. Para la IP privada vamos a usar la librería System.Net. Si el usuario usa un router, el métodos para saber la IP por medio de System.Net no va a servir, por qué? porque va a dar solamente la IP que asigna el router, que no es justamente la IP que le confiere el ISP al usuario que se conecta.

El Sistema está hecho en WPF (El que quiera lo puede hacer para Windows Forms), uso el compilador SharpDevelop.

Vayamos al grano:
La dll se llama MyIPFunction y posee la clase con el mismo nombre además de los siguientes métodos principales, que les transcribo a continuación con la explicaciónd e cada uno:

// Devuelve la IP Pública, la que requerimos para Jugar, para devolver la IP, uso la página //web "http://checkip.dyndns.org/"
LA IP PÚBLICA
private string sIPPublic(){
string s;
try
{
WebClient client = new WebClient();
// Add a user agent header in case the requested URI contains a query;
client.Headers.Add("user-agent""Mozilla/4.0 (compatible;"+
"MSIE 6.0; Windows NT 5.2; .NET CLR1.0.3705;)");

string baseurl = "http://checkip.dyndns.org/";

Stream data = client.OpenRead(baseurl);
StreamReader reader = new StreamReader(data);
s = reader.ReadToEnd();
data.Close();
reader.Close();

s=s.Substring(76);
s=s.Replace("</body></html>""").ToString();

}
catch (Exception)
{ s="0.0.0.0"; }
return s;
}

LA IP PRIVADA
// Devuelve la IP Privada , Listo todas las IP asignadas por el Router y verifico cuál es la mía
private string sIPPrivate()
{
sListIP=new List<string>();
NetworkInterface[] ni = NetworkInterface.GetAllNetworkInterfaces();// Listado de IP

//Después, las recorremos y las tratamos.
foreach(NetworkInterface n in ni)// No uso foreach mucho, pero acá sí
sListIP.Add(n.GetIPProperties().UnicastAddresses[0].Address.ToString());

IPHostEntry host;
string slocalIP = "";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
 {
 if (ip.AddressFamily.ToString() == "InterNetwork")
 {
 slocalIP = ip.ToString();
 }
 }
 return slocalIP;
}
 
DEVOLVIENDO LAS IP
Bien, ahora las IP las devuelvo con las siguientes funciones, que no debería tener necesidad de explicarlas, si necesitás que las explique, volvé a la escuela.

public string sGetIPPublic
{
get{return sIPPublic();}
}

public string sGetIPPrivate
{
get{return sIPPrivate();}
}

SI HAY ROUTER
Y por último, para saber si hay un Router o no conectado, basta con simplemente comparar las IP, la pública y la privada, si éstas son distintas, si son distintas, hay router, si son iguales, simplemente no hay router.
public bool bIsRouter(string ip1, string ip2)
{
return !ip1.Equals(ip2);
}

ENLACES
Que tengan buena vida y hasta el próximo capítulo, les dejo el enlace del código y su debug en mi dropbox.
https://www.dropbox.com/s/vhrk6fb1p07un8c/MyIP.rar?dl=0