Se nos viene WebMatrix 3, mucho más pro!

image

Ya esta disponible para la descarga la versión beta de WebMatrix 3, esta vez con un enfoque mucho más enfocado al desarrollo en la nube, de hecho te pide tus credenciales liveid y puedes acceder a tres meses de desarrollo gratis en la nube Sonrisa.

Hay excelentes características que entusiasman bastante de esta herramienta que es totalmente gratuita:

Podemos editar remotamente un sitio, desde Windows Azure, o un repositorio de código,lo puedes ver en la siguiente imagen:

image

Conectarnos a un repositorio Git o TFS, haciendo esta herramienta mucho más poderosa. Con Git tendremos las opciones que necesitamos desde la herramienta, revisa esto acá:

image

Junto a todas las funcionalidades que esto ya tiene, uff, tremenda herramienta para los developers.

Revisa acá mi post anterior de por que debería interesarte webmatrix:

http://geeks.ms/blogs/gperez/archive/2012/10/29/revisi-243-n-de-por-que-deber-237-a-interesarme-por-webmatrix.aspx

Descárgalo acá:

http://www.microsoft.com/web/webmatrix/next/

image

Invitación WebCast, Trucos para el desarrollo de ASP.NET y VS2012

Hola!, los quería invitar al siguiente WebCast:

Los 10 mejores trucos para el desarrollo en ASP.NET aprovechando al máximo Visual Studio 2012

image

Únete a Gonzalo Pérez (Microsoft MVP) en esta sesión online de más de 100 minutos de entrenamiento técnico en donde desclasificaremos los 10 mejores trucos, consejos y demos para desarrolladores de ASP.NET. Te enseñaremos los secretos para optimizar el desarrollo web, acelerar la implementación con Visual Studio 2012 y aprovechar las nuevas características de esta plataforma.

¡Una sesión imperdible!

Regístrate acá:

https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032546139&Culture=es-CL&community=1

Veremos entre otras cosas:

  • SignalR
  • Knockout.js + mvvm
  • Git + VS2012
  • Bundle Scripts
  • ASP.NET Web API
  • Test de Carga
  • Plantillas Api Facebook , Single Page Application
  • Visual Studio 2012 Page Inspector
  • Productivity Power Tools
  • Bing Maps
  • CSS Inspector
  • Modernizr
  • Typescript

Ufff! muchos temas, así que no se lo pierdan, nos vemos ahí!

Saludos,
@chalalo

[Tutorial] Pizarra Compartida con SignalR y Canvas

Hola, vamos a seguir con SignalR, y digo seguir ya que este sería el segundo artículo, el primero lo puedes ver acá http://geeks.ms/blogs/gperez/archive/2013/02/15/tutorial-comenzando-con-signalr-y-razor-view.aspx

Buscando un ejemplo un poco más entretenido que enviar mensajes pensé que hacer una pizarra compartida, utilizando canvas y la posibilidades de signalR era lo adecuado.

La idea, como aparece en la siguiente figura, es crear una pizarra en donde distintos clientes puedan dibujar al mismo tiempo, además de cambiar los colores del trazo.

image

Backend

Veamos la creación del Backend, el cual está construido como una ASP.NET WEB API muy simple ya que solo es necesario que replique hacia los demás clientes conectados la data que proviene del browser.  Esta Data esta constituida por un Trazo que posee muchos puntos, este trazo corresponde a una línea desde el evento mousedown al evento mouseup cuando se está dibujando, veremos como funciona esto después, por ahora lo importante es la estructura que recibe estos datos.

public class Punto

{

  public string puntox { get; set; }

  public string puntoy { get; set; }

 

  public Punto(string puntox, string puntoy)

  {

    this.puntox = puntox;

    this.puntoy = puntoy;

  }

 

  public Punto()

  {

 

   }

}

Y la Clase Trazo:

public class Trazo

{

  public string color { get; set; }

  public List<Punto> puntos { get; set; }

 

  public Trazo(string color)

  {

    this.color = color;

   }

 

  public Trazo()

  {

   }

 }

Ahora revisemos la clase DibujoConn, que se encarga de manejar las peticiones desde el cliente, solo voy a utilizar los métodos onConnected y onReceived para simplificar al máximo el ejemplo:

public class DibujoConn : PersistentConnection

{

protected override Task OnConnected(IRequest request, string connectionId)

{

   return Connection.Broadcast(new Trazo("0"));

}

 

protected override Task OnReceived(IRequest request, string connectionId,
                                   
string
data)

{

    Trazo trazo = JsonConvert.DeserializeObject<Trazo>(data);

    return Connection.Broadcast(trazo);

           

}

}

Como se puede ver, cuando se establece la conexión se devuelve un nuevo trazo con valor 0 en el color, esto lo utilizo para indicarle al cliente que no es un trazo válido , solo una conexión del usuario.
Cuando se recibe datos desde el cliente, se deserializa, se asigna a un objeto trazo y de devuelve a los clientes.

Luego debemos agregar en el global Asax el endpoint:

RouteTable.Routes.MapConnection<DibujoSignalR.Dibujo.DibujoConn>("dibujo", "/dibujo");

Front-End

Estamos con Razor View, por lo que podemos utilizar sus bondades, voy a utilizar el archivo _Layout.cshtml para definir lo necesario.

<!DOCTYPE html>

<html>

<head>

    <meta charset="utf-8" />

    <meta name="viewport" content="width=device-width" />

    <title>@ViewBag.Title</title>

    @Styles.Render("~/Content/css")

    @Scripts.Render("~/bundles/modernizr")

</head>

<body>

    @RenderBody()

 

    @Scripts.Render("~/bundles/jquery")

    @Scripts.Render("~/bundles/jqueryui")

    @Scripts.Render("~/bundles/jquerysignalr")

 

    @RenderSection("scripts", required: false)

     

<script type="text/javascript">

    inicializar();

</script>

 

</body>

</html>

El archivo Index.cshtml que utiliza este layout es el que contiene el canvas para el dibujo:

@{

    ViewBag.Title = "Pizarra";

}

 

<h2>Pizarra – Chalalo Land</h2>

       <div id="contenedor">

            <div id="no_html5">

              <h2>Tu navegado no soporta Canvas-HTML5</h2>

            </div>

            <div id="contenedor_pizarra">

<canvas id="pizarra" width="600px" height="500px"></canvas>
<
br
/>

<a href="javascript:borrar()" id="borrar_bt">Borrar Pizarra</a>

</div>

</div>

<div id="botones">

 <div class="paleta">

    <button class="boton" id="Black">Negro</button>

    <button class="boton"id="Red">Rojo</button>

    <button class="boton"id="Green">Verde</button>

    <button class="boton" id="Blue">Azul</button>

    <button class="boton" id="White">Goma</button>

  </div>

</div>

@section Scripts { <script src="~/Scripts/pizarra.js"></script> }

Veamos el archivo pizarra.js que se lleva el peso del funcionamiento, puse la explicación en comentarios:

var pizarra_canvas;

var pizarra_context;

/*Definir el objeto trazo*/

var trazo = {

    "color": "#000",

    "puntos": []

};

 

/* Inicializa y determina si el navegador soporta html5- canvas*/

function inicializar() {

    if (!Modernizr.canvas) {

        document.getElementById("contenedor_pizarra").style.display = "none";

 

    } else {

        /* Se establece el ancho de Linea y los Listener para cuando se presiona el mouse

        */

        document.getElementById("no_html5").style.display = "none";

        pizarra_canvas = document.getElementById("pizarra");

        pizarra_context = pizarra_canvas.getContext("2d");

        pizarra_context.lineWidth = 3;

        pizarra_canvas.addEventListener("mousedown", empezarPintar, false);

        pizarra_canvas.addEventListener("mouseup", terminarPintar, false);

      

        /* Este código es para cambiar el color de la linea con respecto a

        el botón presionado, el botón tiene su color en el Id, por lo que se

        asigna a la propiedad de la linea*/

        $(".boton").click(function () {

            pizarra_canvas = document.getElementById("pizarra");

            pizarra_context.strokeStyle = this.id;

            color = this.id;

        });

        /*Esto es implemente para darle el color al botón*/

        $(".boton").each(function (index) {

            $(this).css("background-color", this.id);

        });

    }

}

 

/*En esta función se almacena el primer punto (posición)con el

 que se comenzará a pintar   */

function empezarPintar(e) {

    pizarra_context.beginPath();

    var puntox = e.clientX – pizarra_canvas.offsetLeft;

    var puntoy = e.clientY – pizarra_canvas.offsetTop;

    pizarra_context.moveTo(puntox, puntoy);

    pizarra_context.stroke();

    pizarra_canvas.addEventListener("mousemove", pintar, false);

    trazo.puntos.length = 0;

    var punto = {

        "puntox": puntox,

        "puntoy": puntoy

        };

    trazo.puntos.push(punto);

}

/* Al terminar de pintar, se envía la información (color y trazos) mediante la conexión que provee signalr a la web api,*/

function terminarPintar(e) {

   pizarra_canvas.removeEventListener("mousemove", pintar, false);

    var conn = $.connection("/dibujo");

    trazo.color = pizarra_context.strokeStyle;

    conn.start()

      .promise()

      .done(function () {

           conn.send(JSON.stringify(trazo));

    

      });

}

/* Esta función genera los puntos del trazo, cada uno se va guardando

en la conexión de puntos del trazo para luego transmitirse */

 

function pintar(e) {

    var puntox = e.clientX – pizarra_canvas.offsetLeft;

    var puntoy = e.clientY – pizarra_canvas.offsetTop;

    pizarra_context.lineTo(puntox, puntoy);

    var mipunto = {

        "puntox": puntox,

        "puntoy": puntoy

    };

    pizarra_context.stroke();

    trazo.puntos.push(mipunto);

}

 

 

function borrar() {

 

    pizarra_canvas.width = pizarra_canvas.width;

    pizarra_context.lineWidth = 3;

}

 

$(function () {

    var conn = $.connection("/dibujo");

    /*Esta es la función  que recibe el trazo de todos los clientes conectados. El objeto trazo contiene el color y los puntos, los que se recorren medianteun ciclo for para dibujarlos en pantalla*/

   

conn.received(function (data) {

if (data.color != "0") {

    pizarra_context.beginPath();

    pizarra_context.moveTo(data.puntos[0].puntox , data.puntos[0].puntoy);

    pizarra_context.strokeStyle = data.color;

    for (var i = 1; i < data.puntos.length; i++) {

     pizarra_context.lineTo(data.puntos[i].puntox , data.puntos[i].puntoy );

     pizarra_context.stroke();

    }

  }

});

 

    conn.error(function (error) {

        console.warn(error);

    });

 

    conn.start();    

});

Veamos un video de lo que se puede conseguir con este código, el nivel de abstracción que nos permite signalR es simplemente genial.

 

Ahora si quieres descargar el ejemplo:

DESCARGALO ACÁ

Espero que te sirva:
@chalalo