ASP.NET MVC, WebAPI y Razor, ahora mucho más open source

¿Ein? ¿Pero no lo eran ya? Bueno, sí… pero no en toda la amplitud que puede ofrecer este término.

El progresivo acercamiento de ASP.NET al mundo del open source es algo que llevamos observando bastante tiempo. Desde hace unos años es posible acceder al código fuente de muchos productos, y también hemos visto cómo determinados proyectos puramente libres como jQuery eran incluidos con todos los honores en el conjunto de tecnologías de desarrollo oficiales de la Microsoft. Ahora vamos un paso más allá.

Open Source InitiativeEl código fuente de la primera versión de ASP.NET MVC fue publicado en 2009, poco después de su lanzamiento, bajo licencia MS-PL, un modelo de licencia open source aprobado por la OSI (Open Source Initiative). Desde ese momento, cada lanzamiento del framework iba acompañado de la publicación del código fuente en CodePlex, lo que nos permitía descargarlo, estudiar su funcionamiento, compilarlo, y retocarlo libremente. Lo mismo ocurría con la primera versión de WebPages, y previsiblemente lo mismo iba a ocurrir con las nuevas versiones de MVC, WebPages y Web API.

Sin embargo, el desarrollo de estos productos seguía estando totalmente en manos de Microsoft. Es cierto que podíamos reportar bugs y sugerir cambios, pero en ningún momento participar de forma activa en los proyectos, ni ver lo que iba ocurriendo entre una RTM y otra.

Y de pronto, hoy nos levantamos con la noticia de que ASP.NET MVC, Web API y Web Pages (Razor) van a ser distribuidos como open source (licencia Apache 2.0). Pero si ya podíamos acceder al código fuente, ¿cuál es la novedad?

Pues, en primer lugar, que ahora los proyectos se han abierto totalmente de cara a la comunidad. No se trata de dejar que se vean las tripas de estos productos una vez terminados, sino de adoptar un modelo de desarrollo abierto y transparente al cien por cien.

Para empezar, ya no tendremos que esperar a las versiones RTM para acceder al código fuente, como ocurría hasta ahora; tendremos total transparencia durante el proceso de desarrollo, puesto que el fuente está ya disponible en un repositorio público accesible con Git. Podemos descargarlo, clonarlo, hacer forks, sugerir ideas, ver en cualquier momento el estado de los trabajos, las características pendientes de desarrollo, los bugs subsanados y las modificaciones que se están realizando por parte de los contribuyentes en tiempo real.

ProgramadoresY recalco aquí la palabra “contribuyentes”, que es el segundo aspecto importante de la noticia a la que hacía referencia. No hablamos ya exclusivamente de los equipos de Microsoft que hasta ahora han llevado las riendas: a partir de ahora, los desarrolladores de la comunidad podemos contribuir con parches e implementando funcionalidades de estos tres productos.

De hecho, el primero en estrenarse ha sido Miguel de Icaza, que había sido avisado previamente del movimiento, y ha contribuido añadiendo modificaciones a las plantillas de edición para que tengan en cuenta el DataType (Email, Url, DateTime, Date, Time, Number, etc.) a la hora de generar los controles en la página, de forma que éstos ya aparezcan con el atributo type establecidos de forma correcta para aprovechar las ventajas de HTML5.

Pero ojo, que esto no significa que MVC, Web API o Razor vayan a ser abandonados a su suerte. Microsoft va a seguir incluyéndolos con Visual Studio y trabajando en ellos como hasta ahora, desarrollándolos con la misma gente, dándoles soporte oficial, y asegurando su calidad. Cada contribución será minuciosamente revisada y comprobada por el equipo de ASP.NET y sólo serán aprobadas aquellas que cumplan estrictos criterios de calidad y adhesión al Roadmap de cada producto.

En palabras de Hanselman, nada cambia salvo una cosa: Es ASP.NET, pero ahora puedes involucrarte.

Y las ventajas están claras: estas tecnologías se verán enriquecidas e impulsadas por la comunidad de desarrolladores, y, si no se ponen trabas, esto seguro que se traduce en un crecimiento mucho mayor que el que hemos vivido hasta ahora, una respuesta más rápida ante problemas, una mejor y más eficiente adaptación a los cambios tecnológicos del entorno, y sobre todo, una mayor cercanía de los productos a sus usuarios y a la realidad de nuestro trabajo.

En fin, se trata de un importante movimiento por parte de Microsoft cuyas consecuencias y resultado iremos viendo con el tiempo, pero si todas las premisas se cumplen sin duda es una gran noticia para los desarrolladores ASP.NET.

Enlaces:

Publicado en: Variable not found.

SignalR (III): Más Conexiones Persistentes

Qué divertidoLo divertido de escribir sobre productos que están todavía en fase de desarrollo es que cambian… y a veces, ¡de qué forma! Pues esto ha ocurrido con SignalR: recientemente se publicó la revisión 0.4 y bastantes cosas de las tratadas en el post anterior de la serie ha quedado en agua de borrajas. En fin, estaba avisado, así que mucho no puedo quejarme 😉

Por tanto, esta tercera entrega de la serie vamos a dedicarla (otra vez ;-)) a las conexiones persistentes, veremos qué cosas han cambiado con la llegada de la revisión 0.4, y desarrollaremos un nuevo ejemplo que ilustre las novedades que podemos encontrar a la hora de trabajar a bajo nivel con SignalR.

1. Resumen rápido: persistent connections y la versión 0.4 de SignalR

Para los que ya dominabais SignalR, os resumo las novedades principales que he encontrado hasta el momento en esta nueva revisión:

  • han desaparecido todos los métodos síncronos (OnConnected, OnDisconnect, OnReceived…) que implementábamos en el ejemplo de la segunda entrega de la serie para tomar el control ante determinados eventos de la conexión.
  • por tanto, ahora es obligatorio utilizar las versiones asíncronas (OnConnectedAsync, OnDisconnectAsync, OnReceivedAsync…), que retornan un objeto Task para implementar la lógica de gestión de los eventos.
  • SignalR ha sido desacoplado de ASP.NET, lo que permite utilizarlo en otros entornos. Como consecuencia, la firma de algunos métodos ha sido modificada. Así, cuando somos notificados de una nueva conexión, ya no recibimos el contexto HTTP tradicional, sino abstracciones propias de SignalR y desvinculadas de ASP.NET, lo cual supone alguna pequeña limitación aunque fácilmente salvable.
  • El proceso de negociación utiliza el transporte más apropiado para cada navegador, teniendo en cuenta de los componentes disponibles en servidor. En Internet Explorer se utiliza el transporte “Forever frame”, mientras que Firefox y Chrome usan “Long Polling” cuando el servidor no corre sobre .NET 4.5 (en caso contrario usaría websockets de HTML5).
  • Curiosamente, lo que antes denominábamos “clientId”, que es ese GUID que identifica de forma única a cada cliente conectado, ha pasado a llamarse “connectionId”. No afecta a nada, sigue significando lo mismo, pero es un cambio conceptual destinado a que tengamos claro qué indica ese dato.
  • Ahora, los broadcasts enviados justo durante la conexión de un nuevo cliente incluyen al propio cliente conectado, lo que evita tener que hacer el hack al que nos veíamos obligados en el post anterior (el “ping”).

A continuación desarrollaremos un ejemplo completo para que podemos ver de nuevo en funcionamiento esta maravilla. Como siempre, al final del artículo encontraréis un enlace para descargar el proyecto de demostración, en el que también he modificado el ejemplo que vimos en el post anterior para adaptarlo a los cambios de la revisión de SignalR.

2. Creación de un chat simple con SignalR

En este artículo vamos a complicar ligeramente el ejemplo anterior para construir un pequeño chat al estilo del que encontramos en Facebook, y cuyo aspecto podéis ver en la captura de pantalla siguiente:

Captura de pantalla
De forma muy similar al ejemplo que vimos en el post anterior, necesitaremos:

  • Crear nuestro servicio, como ya sabemos, implementando una clase que herede de PersistentConnection. Llamaremos a esta clase SimpleChatService.
  • Tomar el control cuando un cliente envía un mensaje al servidor, con objeto de hacer un broadcast al resto de usuarios. Esto lo conseguiremos sobrescribiendo el método OnReceivedAsync.
  • También tendremos que registrar la ruta hacia el endpoint, de forma que las peticiones puedan llegar a él.
  • Y, por último, implementaremos el lado cliente, que consistirá en el UI y los scripts que se conectan al servidor, envían los mensajes cuando son tecleados por el usuario, y muestran en pantalla a su vez los textos enviados por otros usuarios.

Vamos con ello.

3. El lado servidor. Asincronía al 100%.

Un sistema basado en SignalR no podría funcionar correctamente si no utilizara las capacidades de asincronía del framework, debido a la gran cantidad de mensajes que pueden llegar a intercambiarse entre cliente y servidor. Por ello, el equipo del producto ha puesto especial énfasis en utilizar métodos asíncronos siempre que sea posible, evitando así bloqueos innecesarios y aumentando la capacidad de respuesta del servicio.

En el post anterior veíamos que podemos tomar el control del sistema cuando los usuarios se conectan, desconectan, o envían información al servidor sobrescribiendo los métodos OnConnected(), OnDisconnect(), y OnReceived() respectivamente. Sin embargo, el uso de esos métodos síncronos podían hacer ver que este aspecto no era importante.

La versión 0.4 ha dado la vuelta a esto, y obliga a utilizar sus equivalentes asíncronos OnConnectedAsync(), OnDisconnectAsync() y OnReceivedAsync(); en estos casos siempre se retornarán objetos de tipo Task, lo que abre la puerta a la paralelización y mejor aprovechamiento de la infraestructura sobre la que estamos corriendo.

Por tanto, comenzaremos la implementación de nuevo servicio heredando de PersistentConnection y sobrescribiendo, aunque de momento con un cuerpo vacío, el método que necesitamos para nuestro chat:

public class SimpleChatService : PersistentConnection
{

    protected override Task OnReceivedAsync(string connectionId, string data)
    {
        // ...
    }
}

Observad el retorno del objeto Task, que representa la tarea asíncrona que iniciamos desde el método. Si el trabajo a realizar en su interior es asíncrono podemos utilizar cualquiera de las vías disponibles para crear un Task, lo retornamos, y listo, por ejemplo así:

    protected override Task OnReceivedAsync(string connectionId, string data)
    {
        return Task.Factory.StartNew(() =>
            // Async task here...
        );
    }

Pero, ¿qué ocurre si la lógica que queremos implementar en ellos es puramente síncrona? Pues no pasa nada, la ejecutaremos y retornaremos una llamada a la implementación por defecto del método, que ya se encarga de devolvernos un Task vacío :-)

    protected override Task OnReceivedAsync(string connectionId, string data)
    {
        // Do some sync work and 
        // then return an empty Task
        return base.OnReceivedAsync(connectionId, data);
    }

Bueno, continuemos con la implementación de nuestro chat. Cuando un cliente nos envíe un texto, lo recibiremos en el método OnReceivedAsync, y lo que queremos hacer es enviarlo al resto de usuarios conectados, ¿no? Pues simplemente usaremos la propiedad Connection disponible en la clase base y llamaremos a su método BroadCast(). Y dado que éste retorna un Task, directamente podremos retornarlo como resultado del método. La implementación completa de la clase queda como sigue:

public class SimpleChatService : PersistentConnection
{
    protected override Task OnReceivedAsync(string connectionId, string data)
    {
        string clientDescription = getClientDescription();
        return Connection.Broadcast(new { user = clientDescription, message = data });
    }
 
    private static string getClientDescription()
    {
        var context = HttpContext.Current;
        var name = context.Request.IsAuthenticated
                        ? context.User.Identity.Name
                        : context.Request.UserHostAddress;
        return name;
    }
}

Chat en funcionamientoMediante la invocación a BroadCast() estamos enviando a todos los clientes conectados un objeto anónimo serializado en JSON. En este caso, dicho objeto contará únicamente con dos propiedades, user y message, que recuperaremos desde el lado cliente para mostrar el mensaje en pantalla junto con el nombre del usuario emisor.

El otro método que aparece en el código, getClientDescription(), es simplemente una ayuda para obtener el nombre del usuario que se mostrará en pantalla, que será el User.Identity.Name si está autenticado, o la IP en caso contrario.

No sé si os estáis dando cuenta, pero, ¡estamos implementando el lado servidor de un mini-chat en menos de diez líneas de código!

4. Rutado de peticiones hacia el endpoint

Como también vimos en el artículo anterior de la serie, para que las peticiones lleguen al endpoint es necesario registrarlo en el sistema de routing. El lugar para hacerlo, como es habitual, será el global.asax:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterSignalrConnections(RouteTable.Routes);
        RegisterRoutes(RouteTable.Routes);
    }
 
    public static void RegisterSignalrConnections(RouteCollection routes)
    {
        routes.MapConnection<SimpleChatService>("SimpleChat", "SimpleChatService/{*operation}");
    }

Esto es todo lo que necesitamos para dejar configuradas las rutas. El parámetro genérico de la llamada a MapConnection() indica la clase que implementa el servicio; el primer parámetro del método es simplemente el nombre de la ruta (no tiene mayor importancia), y el segundo especifica la URL a través de la cual será posible acceder al endpoint.

Y así, podemos pasar ahora a implementar el cliente.

5. El lado cliente

En el proyecto de demostración que podéis descargar al final del post está un poco más trabajado a nivel de interfaz de usuario, aquí vamos a comentar únicamente los principales aspectos a tener en cuenta.

En lo relativo a la presentación, nuestro chat sólo necesita la inclusión del siguiente código en la página:

<div id="chat">
    <div id="chat-messages">
        <!-- Placeholder for messages -->
    </div>
    <form method="POST" action="#" id="chat-form">
        <input type="text" id="chat-message" />
        <input type="submit" value="Send" />
    </form>
</div>

Como podéis intuir, el bloque con identificador “chat-messages” será utilizado, obviamente, para introducir los mensajes que vayamos recibiendo desde el servidor, es decir, los escritos por todos los usuarios que estén participando en el chat. El formulario, por otra parte, simplemente es el mecanismo mediante el cual los usuarios podrán enviar sus mensajes.

Además de esto necesitaremos algunos scripts que le den vidilla al asunto:

    $(function () {
        $("#chat-form").submit(function () {
            var message = $.trim($("#chat-message").val());
            if (message != "") {
                conn.send(message);
            }
            $("#chat-message").focus().val("");
            return false;
        });
 
        var conn = $.connection("SimpleChatService");
        conn.received(function (data) {
            var user = data.user;
            var message = data.message;
            $('#chat-messages')
                .append("<div><strong>" + user + "</strong>: " +
                         message + "</div>"
                );
          
            var sh = $('#chat-messages')[0].scrollHeight;
            $("#chat-messages").animate({ scrollTop: sh }, 3000);
        });
        conn.start();
    });

A grandes rasgos, lo que estamos haciendo es lo siguiente:

  • En primer lugar, creamos y asignamos la función de tratamiento del evento submit del formulario. En su interior, lo único que hacemos es enviar el contenido de la caja de texto “chat-message” al servidor, limpiar dicho control y volver a posicionar sobre él el foco de edición. El texto enviado desde este punto será el que recibimos en el método OnReceivedAsync() que hemos visto anteriormente implementado en el servidor.
  • A continuación, se obtiene una conexión al servicio, almacenándola en la variable conn.
  • Implementamos el callback received sobre el objeto conn, que será invocado cuando se reciban datos enviados por el servidor. El parámetro data será la instancia del objeto anónimo que enviamos desde el servidor mediante el broadcast, por eso podemos usar directamente sus propiedades name y message para añadirlo a la ventana del chat. Finalmente, desplazamos la ventana hasta el final del scroll para que se puedan ver directamente los últimos mensajes recibidos.
  • Por último, iniciamos la conexión llamando a método start() del objeto correspondiente.

Y con esto hemos acabado la implementación de nuestro simplísimo chat. Como os comentaba, en el proyecto de demostración está un poco más trabajado a nivel de interfaz, pero básicamente es lo que hemos visto aquí.

Simplechat SimpleChat

6. Punto extra: agrupación de clientes en SignalR

Hasta ahora, hemos visto que al hacer un broadcast el mensaje es enviado a todos y cada uno de los clientes que se encuentran en ese momento conectados al servicio. Esto es válido en muchos escenarios, pero hay otros en los que necesitamos algún mecanismo para segmentar o agrupar los clientes según determinados criterios.

Un ejemplo clásico serían los chats reales, donde es habitual encontrar “salas”. Los mensajes enviados por un usuario concreto son vistos únicamente por los compañeros de la sala en la que se encuentra, por lo que podríamos considerar que se trata simplemente de un mecanismo de agrupación de usuarios.

SignalR incluye de serie mecanismos para añadir o eliminar usuarios (clientes) a grupos y enviar mensajes a éstos de forma bastante sencilla, mediante los siguientes métodos de la clase PersistentConnection (que, por cierto, también retornan un objeto de tipo Task):

  • AddToGroup(string connectionId, string groupName): agrega el cliente con el identificador clientId al grupo denominado groupName.
  • RemoveFromGroup(string connectionId, string groupName): elimina el cliente clientId del grupo identificado como groupName.
  • SendToGroup(string groupName, object value): envía el objeto value, convenientemente serializado en JSON, a todos los clientes conectados al grupo groupName.

Fijaos que, de momento, el API es bastante simple en lo relativo a los grupos. Por ejemplo, no hay forma de vaciar un grupo, o de consultar los clientes pertenecientes a cada uno de ellos, aunque parece que está previsto ampliar las funcionalidades disponibles en futuras versiones del producto.

De nuevo os animo a que descarguéis el proyecto de demostración y veáis SignalR en ejecución. Un framework que, sin duda, vale la pena conocer por la cantidad de escenarios en los que podemos utilizarlo y aportar ese factor “¡uau!” que comentaba al principio de esta serie.

Publicado en: Variable not found.

Experiencia Summit

Space NeedlePues sí, toda una experiencia, no podría describir de otra forma los días que acabo de dejar atrás. Aún con las avenidas de Bellevue grabadas en la retina, el regustillo amargo de la cerveza Mac&Jac en el paladar, y el aroma a la Kobe Burger del Cheesecake Factory, es un buen momento para hacer una breve retrospectiva de lo que ha sido este viaje.
Primero empezaré contando lo malo, y si hay algo realmente malo de ir al Summit es precisamente el “ir”. Bueno, y el volver ;-).

Para alguien poco curtido en materia viajera como un servidor, saltar a la otra parte del mundo no es tarea sencilla. Es un viaje tan largo que da para todo: turbulencias que te ponían el estómago al revés, retenciones en el control de entrada a Estados Unidos, escalas, y muchas, pero muchas, horas de vuelo tanto transoceánicos (Barcelona-Nueva York) como internos (Nueva York-Seattle). Tanto la ida como la vuelta duraron más de veinte horas, interminables en algunos momentos, aunque bastante bien llevadas gracias a la inestimable compañía de los amigos Marc y Lluis.

Tenía la esperanza de encontrarme con Ballmer por un pasillo y decirle que a ver si la próxima vez podían hacerlo más cerquita, en Cádiz o algo así, pero no ha podido ser 😉 De todas formas, también es cierto que si lo organizaran en otra parte no sería lo mismo.

Otro tema curioso es el cambio horario. Las nueve horas de diferencia entre España y Seattle hacen que se duerma bastante poco; durante los primeros días me despertaba entre las cuatro y las cinco de la mañana, aunque ya después fue mejorando la cosa; eso sí, sólo conseguí dormir ocho horas seguidas el día previo al regreso. Pero a pesar del sueñecillo con el que hay que convivir durante unas jornadas, la verdad es que es un tema que no me ha resultado especialmente duro, ni a la ida ni a la vuelta.

Durante el viaje y estancia el acento americano me ha resultado prácticamente indescifrable. No es la primera vez que salgo al extranjero, ni que tengo que interactuar en inglés, pero siempre había sido en su “versión” británica y más o menos había sido capaz de defenderme. En este caso, cada vez que alguien me hablaba es como si lo hiciese en chino mandarín.

Por ejemplo, una dependienta de un McDonalds de Seattle, una vez acabó de atenderme, me despidió con un amable “Thank you for visiting us”. Entendí algo así como “¿Qué vais a visitar hoy?”. Me pareció raro, pero pensé que la simpática muchacha había notado que era extranjero y quería ser cortés, por lo que le respondí contándole los planes turísticos que teníamos para la tarde: íbamos a visitar el Space Needle, el monorail, Pike Place Market… En fin, podéis imaginar la cara que se le quedó a la muchacha, y las risas que eché cuando me di cuenta de lo que había pasado ;-DDDD

Afortunadamente, en las sesiones técnicas esto cambiaba y las palabras que cazaba eran suficientes para entender el mensaje apoyándome en las proyecciones, normalmente Powerpoints o Visual Studio. Además, sabéis que el lenguaje técnico es bastante más simple y previsible que lo te encuentras por la calle, las expresiones son siempre las mismas, y no cuesta mucho seguir el hilo a una presentación.

Vaya dos pájarosSin tener en cuenta los días que hemos ocupado por completo viajando, han sido en total cinco días de estancia en Bellevue, lo que nos ha dejado tiempo para todo: turismo, sesiones técnicas, networking, compras, divertirnos en buena compañía, y saludar a personas a las que no había tenido oportunidad de conocer hasta este momento.

Y desde luego, no nos podemos quejar de la meteorología. Aunque llevaba en la maleta paraguas y chubasquero por aquello de la “ciudad de la lluvia”, no me ha hecho falta sacarlos en ningún momento. Sé que en algunos momentos llovió, e incluso cayó algo de aguanieve, pero siempre cuando estábamos en el interior de edificios o de noche, y sólo en una ocasión nos dimos un leve remojón de camino al hotel. Eso sí, lo que es el sol la verdad es que se ve poco por allí, el cielo siempre está encapotado y amenazante.

Nos alojábamos en un sitio bastante céntrico de Bellevue, en el hotel Courtyard by Marriot. Las habitaciones eran muy amplias y bien equipadas, y, afortunadamente, con acceso a internet wifi gratuito de calidad bastante razonable –salvo cuando intentabas descargar Windows 8 ó VS11 beta-, lo cual permitía seguir con facilidad lo que iba ocurriendo a este lado del Atlántico, mantener contacto con familia, amigos, clientes, colaboradores, y continuar las labores de tutoría de los cursos de CampusMVP. Además, se encontraba a pocos minutos a pie de los hoteles donde se concentraban gran número de charlas y actividades del evento, el Hyatt Regency y el Westing Bellevue, lo que nos ha venido bastante bien a la hora de planificarnos y movernos por los alrededores.

Rascacielos en Seattle
Visitamos Seattle en dos ocasiones. Estaba bastante cerca de Bellevue, a unos veinte minutos en autobús, y pasamos una tarde de turismo en la ciudad, en la que pudimos pasear por sus avenidas, subir al famoso monorail y al Space Needle, y las obligadas visitas al Pike Place Market y al cercano “Starbucks original”, lo que fue el primer local de la famosa cadena.

Todo un gustazo darse una buena caminata para saborear el ambiente a pie de calle, pero, para los que estamos acostumbrados a ciudades relativamente planas como Sevilla, quizás lo más impresionante es ver por primera los enormes edificios y rascacielos de la ciudad.

La segunda vez que fuimos a Seattle, ya el último día del evento, fue para asistir a la fiesta de clausura del evento, que tuvo lugar en el Century Link Field, el estadio del Seahawks de Seattle, un equipo local de fútbol americano, y del Sounders FC. Un fiestorro por todo lo alto en el que no faltaron animadoras (no puedo poner fotos sin comprometer a algunos amigos, es NDA ;-)), mascotas del equipo, jugadores firmando autógrafos, actividades de ocio, comida, bebida, videojuegos… en fin, una pasada.

También, a otros veinte minutos en autobús estaba el campus de Microsoft en Redmond, que visitamos en varias ocasiones, y que es una de las cosas que más me han impresionado del viaje.
Primero, porque cuando hace tiempo veía fotos de las instalaciones o leía sobre cómo era aquello, en ningún momento se me podía pasar por la cabeza que en algún momento pudiera visitarlo y, segundo, porque es sencillamente impresionante.
Campus de Microsoft, zona "The Commons"
Ya desde que llegas a Bellevue empiezas a ver Microsoft en un gran número de edificios, y empiezas a hacerte una idea del gigante que hay detrás de ese logo que vemos todas las mañanas al arrancar el ordenador. Y sí, es cierto que todos sabemos que es una gran multinacional, que es enorme, descomunal… pero la dimensión real de la compañía la sientes cuando estás allí.

Como ya comentaba el amigo José Manuel Alarcón hace cosa de un año, independientemente de la simpatía o no que se tenga por la casa, sus productos, y sus políticas, las instalaciones de Microsoft en Redmond son dignas de admiración. Avenidas, árboles y jardines perfectamente cuidados, restaurantes, bares, cafeterías, bancos, tiendas, áreas deportivas (al menos un campo de fútbol y una cancha de baloncesto), servicios de transporte interno para desplazarse gratuitamente a través de la inmensa superficie que ocupa, y muchas cosas más que seguro no vi durante las visitas.

Bueno, y seguro que a estas alturas os preguntaréis, “vale, todo eso está muy bien, pero, ¿y los contenidos de las sesiones técnicas? ¿Porque ibas para eso, no?”. Pues la verdad es que poco os puedo contar al respecto :-(

La NDA (Non-Disclosure Agreement, “Acuerdo de Confidencialidad”) es un documento que firmamos al ser nombrados MVP en el que nos comprometemos a no revelar información que Microsoft considera restringida y a la que en algunas ocasiones tenemos acceso. En el Summit todas las sesiones se encontraban protegidas por este acuerdo.

También ha habido oportunidad de conocer en persona a componentes de los distintos equipos de producto y celebrities de este mundillo. Resulta curioso reconocer por los pasillos a gente a la que sigues desde hace mucho tiempo; por allí andaban Phil Haack, Scott Hanselman, Erik Porter, Damian Edwards, David Fowler, Jon Galloway, Daniel Roth… Me quedé con las ganas de ver en directo a Scott Guthrie y Anders Hejlsberg, pero la próxima vez será 😉

Y por lo demás, muchos almuerzos, cenas y sus correspondientes copas posteriores con los componentes de la representación española en el Summit, en las que, al menos un servidor, ha disfrutado del enorme nivel humano, técnico y el gran sentido del humor que se gasta en el grupo. Vamos, que me lo he pasado de fábula :-)

Publicado en: Variable not found.