piątek, 12 kwietnia 2013

Node.js + Edge.js (2)

Dziś poruszę wywoływanie skompilowanego assembly .NET z poziomu node.js.

image

Na początku zaznaczę, że nie bedę opisywać wszystkich zagadnień i szczegółów związanych z komunikacją JavaScript (node.js) i .NET 4.5 (maszyna wirtualna CLR hostowana w procesie node.js). U mnie to będzie konkretny praktyczny przykład takiej komunikacji. Do pełnego zrozumienia omawianej tematyki polecam zapoznanie się z informacjami pod trzema adresami:

Edge.js jest dzieckiem Tomasza Janczuka, który w Microsoft najpierw zajmował się serwisami danych, później komunikacją w Silverlight, a obecnie jego zadaniem jest tworzenie rozwiązań w oparciu o node.js, JavaScript i Windows Azure.

Po co takie wywoływanie .NET z node.js?  Chcemy oczywiście jak najwięcej nowych rozwiązań, ale nic nie jest idealne. W zależności od zmieniających się warunków i priorytetów może czasami chcielibyśmy dać sobie elastyczną furtkę, by wykorzystać część dotychczasowego kodu w C#?  Po drugie przepisywanie w wielu przypadkach nie ma żadnego sensu, chyba że rzeczywiście coś na tym zyskamy np. większą wydajność, większą niezawodność czy większą wygodę używania. Jednak skompilowany C# czy C++ na pewno będą wydajniejsze niż JavaScript (choć ostatnio pojawia się prekompilacja tego ostatniego).

Wróćmy do node.js.  Załóżmy, że czasami mamy działający “legacy code” w .NET, którego nie chcemy przepisywać. Może to być coś w stylu poniższego kodu:

image

Przejdźmy do integracji. Załóżmy najpierw, że ten kod zostanie umieszczony razem z kodem integracyjnym w jednym assembly .NET 4.5. Kod integrujący wygląda w następujący sposób:

image

Zawsze musi być klasa o nazwie Startup, która zawiera jedną lub więcej metod koniecznie o sygnaturze Func<object,Task<object>>. Ta asynchroniczność jest zawsze potrzebna, nawet gdy wykonujemy w C# prostą synchroniczną operację typu 2+2. Dlaczego?  Node.js jest jednowątkowy, CLR jest wielowątkowy, ma inny model, to zupełnie inne środowisko. Przejdźmy do wywołania powyższego kodu z poziomu TypeScript/JavaScript:

image

Assembly z kodem “legacy” i kodem integrującym znajduje się w głównym folderze serwera. Całość ładnie działa i dostajemy JSON-a w oknie przeglądarki:

image

Jak debugować powyższy kod .NET w node.js?  Bardzo prosto! Uruchamiamy nasz serwer w konsoli i attachujemy się w Visual Studio 2012 do procesu node.exe (możemy sobie wybrać, jaki rodzaj debuggera chcemy użyć, powinien być tutaj do kodu zarządzanego CLR 4.0/4.5). Zgodnie z opisem autora Edge.js to po prostu działa! Zresztą praktycznie wszystko można debugować. W przypadku C# oprócz postaci skompilowanej jest to także możliwe dla postaci skryptowej (w prawie wszystkich przypadkach).

A co, jeśli mamy “legacy” kod w skompilowanym assembly dla starszej wersji .NET, np. 4.0?  Sprawdziłem również taki scenariusz umieszczając kod integrujący w assembly dla .NET 4.5, które odwołuje się do assembly .NET 4.0. Obie biblioteki umieściłem obok siebie, jak w przykładzie powyżej. Również wszystko ładnie działa (zgodnie zresztą z teorią).

Podsumowując, łączenie node.js z .NET wygląda całkiem zgrabnie, choć daleko do bezszwowej integracji jaką oferuje Windows Runtime -;) Ale wynika to pewnie z zupełnie innego podejścia do obsługi wątków w node.js i w CLR .NET. Tutaj mamy dopasowanie do czegoś, co jest tworzone z myślą o różnych systemach operacyjnych i jest zasadniczo oparte o JavaScript. W WinRT twórcy mieli wpływ na całość rozwiązania, więc mogli zrobić to lepiej.  Ale ogólnie edge.js to super rewelacja!  Będą liczne integracje z rozwiązaniami Microsoft (m.in autentykacja ASP.NET, kryptografia, obsługa certyfikatów w magazynie, Event Log, komunikacja z serwisami SOAP i WCF, Active Directory, MS SQL). O planach rozwoju można przeczytać na http://tjanczuk.github.io/edge/#/24.

BTW jeśli chodzi o języki w Edge.js, to możliwe jest napisanie wsparcia dla każdego języka CLR, natomiast na obecny moment wspierany jest C# (w postaci skompilowanej i jako skrypt dynamicznie kompilowany) oraz Python.

Brak komentarzy: