"Realtime Web mit Socket.IO".
Transcription
"Realtime Web mit Socket.IO".
Fachartikel Das Realtime Web – Einblick mit Socket.IO von Michael Piendl, Lead Consultant, Alegri International Services GmbH Grundlagen Unterwegs im Web von heute In den letzten Jahren ist viel passiert. Google, Facebook, Twitter und viele andere Dienste wurden ein fester Bestandteil unseres Lebens. Onlinebanking, Kartendienste, Musikstreaming, Video und vieles mehr hat im Netz einen Milliardenmarkt geschaffen. Doch während es die großen Konzerne wie Amazon, Microsoft, Google, - die Liste wird hier einfach zu lange - geschafft haben ansprechende und hochskalierbare Webangebote zu erstellen, dümpeln viele Anwendungen in Unternehmen und öffentlichen Stellen auf dem gefühlten Niveau der 90er Jahre herum. Zwar haben die meisten Unternehmen bereits Kooperationen mit Designbüros; wenn es um die Umsetzung von Internetauftritten geht, aber gerade bei internen Anwendungen geht es oftmals drunter und drüber. Wenn das Auge sich schon nicht erfreuen kann, dann könnte man ja annehmen, dass zumindest technologisch sich die Anwendungen auf Augenhöhe bewegen. Doch auch hier leider oftmals weit gefehlt. Viele Entwickler setzen auf Frameworks wie ASP.NET Web Forms. Dagegen spricht absolut nichts! Man sollte jedoch nicht die Best-Practices von 2002 verwenden, sondern mit der Zeit gehen und wie die Entwickler von Microsoft sich in den Frameworks genau ansehen, was heute relevant ist und was nicht. Nur weil eine Idee vor 12 Jahren revolutionär war, bedeutet dies nicht, dass sie heute noch gut und zeitgemäß ist. Das Web hat sich entwickelt – und mit ihm die Anforderungen an die Entwickler.Checklist: What NOT to do in ASP.NET http://www.hanselman.com/blog/ChecklistWhatNOTToDoInASPNET.aspx Geschichte des Internet mit HTTP Am Anfang stand eine großartige Idee. Als Tim Berners-Lee Anfang der 90er Jahre HTTP entwarf, war die Vision des Internet noch eine andere, als das, was wir heute kennen. Die Idee war relativ simpel. Ein Browser sendet eine Anfrage (Request) an einen Server. Diese Abfrage enthält neben der Art der Anfrage (GET, POST, PUT usw.) die genaue Adresse (URL) und Meta-Informationen (Header). Der Server antwortet auf diese Informationen (Response) mit einem Status Code (z.B. 200 OK oder 404 Not Found) und den gewünschten Daten. Nimmt man nun als Daten HTML, CSS, Bilder und JavaScript, so findet man sich in unserem heutigen Web wieder. Das einfache Prinzip von „Request des Browser -> Response vom Server“ für jede einzelne Ressource ist in seinem Kern bis heute fast unverändert. Im Laufe der Geschichte wurde die Idee durch findige Entwickler oft erweitert. Während in der Anfangszeit die Dokumente auf dem Server statisch waren, fand sich kurz darauf die Idee, diese Inhalte bei jeder Anfrage dynamisch zu genieren. War es nicht spannend, wenn man als FrontPage Bastler zum ersten Mal Frameworks wie PHP entdeckte und plötzlich zaubern konnte. Dieses Zaubern am Server betreiben wir bis heute. Dazu kam aber noch die Dynamik im Browser. Statt alles den Server erzeugen zu lassen, hat JavaScript die Programmierung im Client übernommen. Am Anfang stand einfaches Ein-/Ausblenden von Elementen. Heute bewegen wir uns mit ASM.JS bei Beispielen wie der Unreal Engine für 3D Spiele im Browser – natürlich ohne Plugin. Der Sprung zu AJAX und SPA Die Seiten wurden von Jahr zu Jahr umfangreicher und komplexer. Irgendwann schien es für gewisse Szenarien nicht mehr sinnvoll, die ganze Seite erneut vom Server laden zu lassen. Es kam die Idee auf, Fragmente oder Daten dynamisch nachladen zu können. Die Idee für XmlHttpRequest war geboren. Bald fingen die ersten prominenten Beispiele wie Outlook Web Access oder Google Maps an, ohne unser Zutun dynamisch Daten vom Server nachzuladen. Ein „Killerfeature“, bei einem offenen OWA eine Nachricht zu erhalten, dass eine neue Email angekommen war, ohne dass der Anwender vorher ständig F5 drücken musste. Der Hype hat dann vor ein paar Jahren gezündet und AJAX wurde eine wichtige Grundlage für jeden Web Entwickler. Viele Anwendungen haben sich grundlegend verändert. Plötzlich lieferten die Server via WCF, WebAPI oder anderen Frameworks eher Daten als Seiten. Statt XML hat sich JSON als Datenformat in vielen Bereichen durchgesetzt. Gerade Frameworks wie Knockout, Angular oder Ember gingen sogar mit dem Ansatz von SPA (Single Page Applications) den extremen Schritt. Statt immer wieder Seiten vom Server zu laden, wird hierbei initial nur noch eine HTML Datei geladen. Alle weiteren Manipulation der Darstellung und Daten werden via JavaScript vorgenommen. Der Code lädt dabei über AJAX Requests alles, was er vom Server benötigt. Der Browser wurde langsam von der reinen Anzeige zum echten Applikationsframework. Viele dieser Technologien verstehen wir heute unter dem Namen HTML5. Realtime mit COMET und WebSockets Gerade im Beispiel von OWA mit der Prüfung auf neue Nachrichten wurde bald ein Problem der Architektur offensichtlich. Beim HTTP ging man immer davon aus, dass nur ein Client eine Anfrage initiiert. Der Server hatte keine Möglichkeit, proaktiv dem Client Nachrichten zukommen zu lassen. Doch findige Entwickler fanden auch hier verschiedene Möglichkeiten, welche sich heute unter dem Begriff COMET sammeln. Es handelt sich dabei um ein bekanntes Neologism für Ansätze wie Reverse AJAX, Ajax Push, xhr-streaming, xhr-polling und viele mehr. Die technische Umsetzung basiert immer auf der Tatsache, dass der Browser einen Request erstellt, welcher vom Server nicht direkt beantwortet wird. Der Server hält die Verbindung aber offen, wodurch sich der Name „Long Pool“ etablierte. Sobald der Server einer Nachricht für den Client hat, erstellt er den Response und schickt diesen auf dem offenen Kanal zurück. Der Browser verarbeitet die Informationen und stellt sofort eine neue LongPool Anfrage an den Server. Viele der Implementierungen nutzen hierbei auch TimeOut Nachrichten und verwenden neben XmlHttpRequest auch IFrames oder ScriptTags. Die Lösungen sind vielzählig. Das IETF hat diese Thematik dann vor einigen Jahren aufgegriffen. Statt den bisherigen Lösungen wollte man eine leistungsfähige Alternative schaffen. Das Ergebnis dieses Prozess waren HTML5 WebSockets. Mit WebSockets wird ein full duplex bi directionaler Kanal zwischen dem Client und dem Server aufgebaut. Dieser Kanal bleibt im Gegensatz zu normalen HTTP Anfragen offen. Diese Verbindung ermöglicht schnelle und skalierbare Kommunikation vom Server zum Client. Bei typischerweise kleinen Nachrichten spricht man von einer Einsparung des Header Traffic von 500:1 – 1000:1. The WebSocket Protocol (RFC 6455) https://tools.ietf.org/html/rfc6455 Einsatzszenarien Natürlich ist diese neue Art der Kommunikation nicht für alle Arten von Web Seiten und Web Anwendungen geeignet. Wer die Öffnungszeiten seiner Kantine darstellen will braucht keine WebSockets. Auch die Darstellung weiterer statischer Daten ist oft auf bisherigem technologischem Stack besser abbildbar. Doch es gibt genügend Bereiche, die heute davon stark profitieren können. Das Beispiel mit der Benachrichtigung bezüglich neuer Daten hatten wir ja bereits. Dies betrifft nicht nur OWA, sondern auch Plattformen wie Facebook, SharePoint und Yammer. Gerade bei langlaufenden Prozessen ist die eine große Hilfe. Ein schönes Beispiel ist hier das Management Portal von Azure. Wird eine virtuelle Maschine erstellt, so dauert dies natürlich ein paar Minuten. Der Benutzer startet den Prozess und sobald er abgeschlossen ist, erhält er eine Benachrichtigung in der Anwendung. Ein weiteres Beispiel ist die Darstellung von Live Daten. Dies können beispielsweise die Messdaten einer Maschine sein oder auch Börsendaten. Vielleicht auch nur die Live Darstellung von Log Daten. Treibt man die Ideen weiter, kommt man in die Bereiche von Online Chats. Angefangen von einfachen Kundenchats auf der Seite über Browser-Konsolen zur Ausführung von PowerShell auf dem Server bis hin zur gemeinsamen, gleichzeitigen Bearbeitung von Dokumenten wie in Word Online. Kaum ein Entwickler wird Word Online nachbauen. Aber es wäre doch schön, in einem Dashboard zur Systemüberwachung Live Daten zu sehen. Oder in seinem Ticket-Tool an einem Ticket direkt wie bei Facebook kommentieren und chatten zu können. Auch bestehende Ansätze können angepasst werden. Warum muss eine Suche 1 Anfrage mit 1 Antwort sein? Wäre es nicht sinnvoll, nach einer Anfrage von verschiedenen System aktiv Informationen zu erhalten, die dann kombiniert und angezeigt werden können? Wieviel Umsatz mehr macht eBay wohl, weil der Kunde 5 Sekunden vor Ende sieht, dass er überboten wurde? Socket.IO SocketIO Grundlagen Wie bei vielen dieser Technologien ist die Freude und Spannung erst groß, sobald man sich aber sein Arbeitsumfeld ansieht, herrscht schnell Ernüchterung. Während Chrome und Firefox den Standard HTML WebSocket schön etwas länger implementieren, können wir erst seit IE 10 diesen auch im IE nutzen. Und dies in einer Zeit, in der viele große Konzerne noch IE 8 einsetzen. Was nun, aufgeben und 5-10 Jahre warten? Vor ein paar Jahren fand der Betriff NodeJS im Flurfunk vieler Entwickler Einzug, bereits am Anfang oft mit Frameworks wie Express, Connect und Socket.IO gekoppelt. Die Mini Anwendungen waren für viele beeindruckend und fremd zugleich. Socket.IO hat als einer der ersten bekannten Frameworks genau das vollbracht, was schon in vielen anderen Bereichen üblich war. Es stellt eine Logik bereit, die für den Entwickler leicht verständlich war, und im Hintergrund selber entschied, ob WebSockets oder ein Fallback auf alte COMET Technologien notwendig war. Für den Entwickler war es das Realtime Web, egal ob via WebSocket oder LongPool. Das einfachste Beispiel hebt das neue Muster wunderbar hervor. Beide Seiten, Browser und Server, können sowohl Nachrichten empfangen als auch versenden. Für den Entwickler ist die Art der Kommunikation dabei nicht relevant. server.js var io = require('socket.io').listen(80); io.sockets.on('connection', function (socket) { socket.emit('news', { hello: 'world' }); socket.on('my other event', function (data) { console.log(data); }); }); client.js <script src="/socket.io/socket.io.js"></script> <script> var socket = io.connect('http://localhost'); socket.on('news', function (data) { console.log(data); socket.emit('my other event', { my: 'data' }); }); </script> http://socket.io/ https://github.com/learnboost/socket.io Architektur und Handshake Socket.IO abstrahiert also die technische Verbindung zwischen Client und Server. Dies wird gemacht, um auch alte Browser oder alte mobile Endgeräte zu unterstützen. Die jeweilige Verbindung bezeichnet man hierbei als Socket. Es wird sogar mit Hilfe von Namespaces ermöglicht, gleichzeitig mehrere aktive Sockets auf einer Verbindung zu betreiben. Das Framework stellt durch Heatbeats, die in regelmäßigen Abständen die Reaktion der Gegenstellen überprüfen, sicher, dass diese Sockets auch offen und aktiv sind. Geht die Verbindung kurzzeitig verloren, z.B. im Zug, so ist auch entsprechende Logik für einen automatischen Reconnect und die Zwischenspeicherung der zu übertragenden Daten enthalten. Die Anfrage, einen solchen Socket zu öffnen, kommt vom Client. Dieser hat verschiedene Zustände je Socket, in denen er sich befinden kann. Der erste Zustand ist „connecting“. Hier wird ein Handshake mit dem Server ausgeführt. Dabei erhält der Socket eine eindeutige ID vom Server sowie Konfigurationsinformationen für den Heartbeat und Timeouts. Sobald der Handshake abgeschlossen ist, wechselt der Zustand auf „connected“. Sollte nun zwischendurch ein Verbindungsproblem auftreten, so werden die Nachrichten gebuffert. Wird der im Handshake vereinbarte Timeout überschritten, wechselt der Socket in den Status „disconnected“. Dann ist auch wieder ein „Reconnect“ mit einen neuem Handshake erforderlich. War ein Handshake erforderlich, wird auf dem Server das Event „connection“ geworfen. Der socket Parameter enthält alle notwendigen Informationen der neuen Verbindung. Es soll entsprechend für weitere Kommunikationen mit dieser offenen Verbindung verwendet werden. An dem Socket Objekt kann nun via „on“ auf beliebige Nachrichten gehorcht werden. Die eindeutigen Zeichenketten müssen lediglich mit dem Client abgestimmt sein. Im Hintergrund der Implementierung handelt es sich hierbei um Parameter in einem URL Pfad. Arten der Kommunikation Dass der Client seine Nachrichten an den Server schickt, sollte keinen mehr überraschen. Wenn der Server aber nun Nachrichten verschickt, stellt sich die Frage: an welchen Client? Socket.IO bietet hierfür verschiedene Möglichkeiten. Wird die Socket Instanz verwendet, wird auch nur dieser entsprechende Client angesprochen (Beispiel 1). Mit der emit Funktion des Socket Objekts selbst können alle Clients angesprochen werden (Beispiel 2). Findet die Benachrichtigung durch den Aufruf eines Client statt, kann mit Hilfe von Broadcast schließlich auch noch sichergestellt werden, dass alle Clients außer diesem angesprochen werden (Beispiel 3). // Beispiel 1 – Nur diese Socket socket.emit(‚message‘, ‚hello world‘); // Beispiel 2- Alle Sockets io.sockets.emit(‚message‘, ‚hello world‘); // Beispiel 3 – Alle Sockets außer der aufrufende socket.broadcast.emit(‚message‘, ‚hello world‘); Mit diesen Möglichkeiten sind alle Grundlagen für die vorher genannten Szenarien geschaffen. Um den Entwicklern die Arbeit leichter zu machen, sind allerdings bereits weitere Konstrukte wie beispielsweise Räume mit in das Framework implementiert. Wie bei Chat Räumen kann ein Socket einfach einem Raum beitreten und diesen auch wieder verlassen. Nachrichten können dann einfach an diese Räume geschickt werden. // Raum betreten socket.join(‚myRoom‘); // Nachricht an alle Sockets im Raum io.sockets.in(‚myRoom‘).emit(‚message‘, ‚hello world‘); // Broadcast an alle Sockets im Raum – außer dem Sender socket.broadcast.to(‘myRoom’).emit(‘message’,’hello world’); Sollten einfache Räume nicht ausreichen, so ist auch das Konzept von Namespaces vorgesehen. Jeder socket verbindet sich auf einen Namespace. Jedoch können, wie bereits vorher erwähnt, mehrere Sockets zu einem Client parallel geöffnet sein. Server var io = require('socket.io').listen(80); var chat = io .of('/chat') .on('connection', function (socket) { socket.emit('a message', { that: 'only' , '/chat': 'will get' }); chat.emit('a message', { everyone: 'in' , '/chat': 'will get' }); }); var news = io .of('/news') .on('connection', function (socket) { socket.emit('item', { news: 'item' }); }); Client var chat = io.connect('http://localhost/chat') , news = io.connect('http://localhost/news'); chat.on('connect', function () { chat.emit('hi!'); }); news.on('news', function () { news.emit('woot'); }); Neben diesen grundsätzlichen Funktionen bietet Socket.IO noch eine Reihe weiterer schöner Hilfen. So kann beispielsweise in die Kommunikation noch eine Bestätigung eingebaut werden, um die Übertragung von Daten zu bestätigen. Hierzu wird die emit Funktion noch mit einem Callback ausgestattet. Server socket.on(‚msg‘, function (data, cb) { cb(“super!”) }); Client socket.emit(‘msg’, ‘data’, function(feedback) { // feedback = “super!” }); Authentifizierung Solange man sich wie in den kleinen Beispielen oben die Grundlagen erarbeitet, ist die Welt in Ordnung. Sobald man sich aber in die Richtung von produktivem Code begibt, müssen Aspekte wie Sicherheit und Stabilität genauer betrachtet werden. Die Authentifizierung mit der Web Seite zum Laden des HTML ist erst einmal unabhängig von der Authentifizierung des Socket. Hierzu bietet das Framework aber zwei Möglichkeiten, die wir nutzen können. Wir konzentrieren uns nun auf die globale Authentifizierung. Wer allerdings wie im Beispiel oben mit Namespaces arbeitet, kann zusätzlich auch für diese weitere Ankerpunkte finden. Die globale Authentication findet im Zuge des Handshake statt. Die Authentication wird also globaler EventListener am Socket Objekt registriert. Der Callback liefert dann neben dem HandshakeDataObject Information mit wie Time, Header, Url und Query auch einen weiteren Callback zur Bestätigung. Der Code des Entwicklers kann also nun die eigentliche Authentifizierung durchführen und das Ergebnis inkl. möglichem Fehlertext an Socket.IO übermitteln. Oftmals wird nicht nur die Anmeldung geprüft, sondern im gleichen Schritt auch weitere Metadaten zum Benutzer und der Sitzung an dem neuen Socket gespeichert. Dies kann später in der restlichen Anwendung wiederverwendet werden. io.set('authorization', function (handshakeData, cb) { findPerson(handshakeData, function(err, data) { if(err) return cb(err, false) if(data.isAuthorized) { handshakeData.myInfo = data.myInfo; cb(null, true); }else { cb(null, false); } } }); Häufig findet die Authentifizierung basierend auf den Cookies statt. Diese wurden bei der Anmeldung an die Hauptanwendung ausgestellt und können im Code dann einfach abgeglichen werden. Es gibt inzwischen auch jede Menge NPM Pakete, die genau hier ansetzen und diese Aufgabe übernehmen. Als Beispiel sei passport.socketio genannt. Doch auch gerade in der Zusammenarbeit mit Frameworks wie express gibt es hier jede Menge Alternativen im Netz zu finden. Sehr empfohlen werden kann beispielsweise der Blogpost „Token-based Authentication with Socket.IO“ von José F. Romaniello. http://blog.auth0.com/2014/01/15/auth-with-socket-io/ Skalierung Ein weiteres Problem, das sich dem Entwickler stellt, ist die Skalierbarkeit. Wer sich mit NodeJS auseinandersetzt, erfährt schnell, dass alles in einem Thread stattfindet. Die Vorteile bezogen auf die Geschwindigkeit und den Programmierstil werden umfassend in vielen Artikeln diskutiert und beschrieben. Socket.IO läuft in dieser Umgebung. Der erste Schritt der Skalierung wäre es also, mehrere Prozessorkerne zu nutzen. NodeJS stellt hierzu sein Modul cluster bereit, welches es ermöglicht, einen Master und je Kern einen Slave zu erstellen. Somit läuft pro Kern ein eigener Thread. Wir hätten nun ein Problem, wenn diese Threads nichts mehr voneinander wissen. Wie sollte sonst ein Broadcast funktionieren? Zum Glück löst auch dieses Problem bereits Socket.IO für uns. In der einfachen Variante ist ein MemoryStore integriert. Dieser ermöglich zumindest schon mal die Skalierung bei mehreren Threads innerhalb eines Prozesses. Wir können aber nun ja auch einfach noch mehrere Prozesse von NodeJS mit unserem Server starten. Nun haben wir den Punkt erreicht, wo anderes Stores wie Beispielsweise Redis zum Einsatz kommen. io.set('store', new SocketIO.RedisStore); Will man nun sogar noch über mehrere virtuelle oder physikalische Maschinen hinaus skalieren, muss ein Konstrukt wie der Azure ServiceBus verwendet werden. Das Microsoft Team rund um Azure hat sich hierzu die Zeit genommen, für Socket.IO eine entsprechende Schnittstellte zu entwickeln. Dieses Paket socket.io-servicebus kann ganz normal via NPM geladen werden. var sio = require('socket.io'); var SbStore = require('socket.io-servicebus'); var io = sio.listen(server); io.set('store', new SbStore({ topic: topicName, connectionString: connectionString })); https://github.com/WindowsAzure/socket.io-servicebus Alternativen und Ausblick Entwicklung von Socket.IO Wer sich nach diesem ersten Einblick nun begeistert auf dieses Thema stürzen will, sei gewarnt. Der Bereich NodeJS und damit auch Frameworks wie Socket.IO sind mit der Welt von ASP.NET oder anderen Microsoft Frameworks schwer vergleichbar. In der Open Source Welt gibt es viele Leute mit ähnlichen Ansätzen und entsprechend statt ein paar großen viele kleine Frameworks. Viele davon haben den Betastatus nie verlassen. Viele werden noch nicht einmal die Konzeptphase verlassen. Der aktuelle Stand von socket.io-servicebus ist beispielsweise noch 0.0.3. Oft finden sich hinter den Frameworks Gruppen von hochtalentierten und hochmotivierten Entwicklern, die große Teile Ihrer Freizeit für den Erfolg solcher Frameworks opfern. Wer sich in diese Welt begibt und an der Speerspitze der Technologien mitschwimmen will, kann nicht immer davon ausgehen, dass alles fertig ist und er sich ins gemachte Bett legen kann. Viele Punkte sind offen – ebenso wie der Code. Verstehen, Fixen und Erweitern ist angesagt. Die Communities freuen sich auf jeden, der zum Erfolg beiträgt. Socket.IO selbst erreichte großen Ruhm vor ein paar Jahren. Viele Konferenzen hatten Vorträge darüber. Die fehlende Aktivität auf der Internetseite und in GitHub hat aber bereits Leute dazu veranlasst, über den Tod des Frameworks zu spekulieren. Derweilen gab es vor längerer Zeit die Überlegung, den Kern von Socket.IO in einen eigenen Framework Engine.IO auszulagern. Seit Monaten wird die Version 1.0 von Socket.IO erwartet. Der Urvater von Socket.IO Guillermo Rauch traf sogar vor ein paar Tagen erst folgende Aussage zu Version 1.0 von Socket.IO bei Twitter: „master is pretty stable. Release is imminent“. Die Alternativen: Engine.IO, SockJS, Primus und viele mehr. Einige Frameworks wurden bereits als Alternativen entwickelt. Manche davon nutzen aber auch wieder Engine.IO als Grundlage. Andere Frameworks wie SockJS bilden die API von WebSockets nach und nutzen COMET Technologien für den Betrieb in alten Browsern. Die Argumente der verschiedenen Frameworks sind vielzählig. Während sich Frameworks wie Engine.IO und SockJS eher auf die Grundlegende Kommunikation beschränken, bieten Frameworks wie Socket.IO bereits weitere Funktionalitäten wie Räume und Namespaces. Andere Frameworks wie Meteor enthalten in sich auch Alternativen zu Socket.IO, aber eben als integrierten Teil der Frameworks. Auch in der Microsoft Welt hat sich in den letzten Jahren mit SignalR der Ansatz für .NET Entwickler breit gemacht. Und die Entwicklung wird so schnell kein Ende nehmen. Wer sich fünf Minuten Zeit nimmt und mit den richtigen Schlagwörtern bei Google sucht, wird regelrecht erschlagen von weiteren Alternativen. Es war entsprechend auch nur eine Frage der Zeit, bis die ersten Wrapper Frameworks auftauchen. So gibt es beispielsweise mit Primus inzwischen ein Framework, bei dem die Realtime Frameworks: Engine.IO, WebSockets, BrowserChannel, SockJS und Socket.IO dynamisch ausgetauscht werden können. Auch auf dieser Abstraktion finden sich dann zusätzlich weitere Plugins für Funktionalitäten wie Authentifizierung, Skalierung und vieles mehr. https://github.com/LearnBoost/engine.io https://github.com/sockjs https://www.meteor.com/ http://signalr.net/ https://github.com/primus/primus Persönliches Fazit Das Thema ist zu wichtig, um es einfach zu ignorieren. Während ein Großteil der Entwickler langsam anfängt, einen Einblick in diese neue Art des Web zu erhalten, fangen die bekannten Server Plattformen an, sich an diese Grundlagen anzupassen. Mit aktuellen Projekten wie Helios verlässt Microsoft die ASP.NET Web Forms Pipeline hin zu einen effizienteren Web Server. Das von Google entwickelte SPDY findet langsam aber sicher Zuspruch im Web. Konzepte aus NodeJS und Socket.IO wandern mit Frameworks wie SignalR in die Welt des normalen ASP.NET Entwicklers. Die Umstellung der Kommunikation hat tiefgreifende Auswirkungen auf den Entwurf von Plattformen und die Wahl der Technologien. Diese Auswirkungen wird auch bestehende große Systeme wie SharePoint Stück für Stück in Beschlag nehmen. Entsprechend ist jetzt die richtige Zeit, sich mit diesen Themen auseinanderzusetzten und spätestens jetzt erste Schritte mit diesen Konzepten zu gehen. Viel Erfolg! Über Alegri International Group Alegri International ist ein führendes IT--Beratungsunternehmen im Bereich aller MicrosoftProdukte inkl. SAP-Integration und SAP-Prozessberatung. Durch diese Spezialisierung ist Alegri einer der wenigen Consulting-Partner von Microsoft, der das Zusammenspiel der Applikationen beherrscht: von der Strategischen Planung, Einführung und Installation bis zum Betrieb der Umgebungen: SharePoint, Search, Dynamics CRM, Lync, Duet Enterprise, Windows 8 App, System Center, Azure, Office 365, .Net, SQL Server und Managed Services. Alegri International beschäftigt rund 290 Mitarbeiter in den Hauptgeschäftsstellen München, Stuttgart, Mannheim, Frankfurt/M., Köln, Hamburg, Basel, Zürich, Wien, Cluj-Napoca. www.alegri.eu