Upload
alessandro-pilotti
View
12.033
Download
4
Tags:
Embed Size (px)
DESCRIPTION
My session at ITCamp.ro 2012: Web site development is an ever changing landscape. Thanks to the latest web browser technologies it's possible to create highly responsive single page applications, requiring a new approach to design and development on the server side. During this session we'll see ho to use .Net technologies to get the best out of the new Web API, WebSockets and the excellent RSignal framework.
Citation preview
itcampro@ itcamp12# Premium conference on Microsoft technologies
Building modern web sites with ASP .Net
Web API, WebSockets and RSignal
Alessandro PilottiMVP ASP.Net / IISWindows Azure Insider@alexpilotti
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & DevelopmentITCamp 2012 sponsors
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• ASP.Net Web API• SignalR• WebSocket
Agenda
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• The web app designer’s holy grail:– Reach the usability level of a desktop app
• The web app designer’s curse:– Lack of standard API on the browser’s side
• Until recently the only way out was a RIA framework:– Flash / Silverlight
What’s the deal?
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• HTML5 is changing the game• Great set of new browser features:– Application cache– Web storage– WebSockets– WebWorkers– Geolocation– Drag&Drop– Multiple file uploads– Inline SVG– History management– … and that Video thing
HTML5
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• Javascript is getting a huge boost– There’s more than meets the eye– Its prototyping nature and flexibility is great
• The rest sucks
• An enormous amount of frameworks are available today, e.g:– JQuery / JQuery UI– Knockout.js– Backbone.js– Underscore.js– History.js– …And a gazillion more
Javascript?
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• Single Page Applications– A single HTML is loaded in the browser– History (aka back button) is managed via
Javascript– Templates are used to load and render in
the DOM content on demand• Some Ajax might be useful for that
– Offline usage• Application cache• Web storage
SPA
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• Web pages communicate with the server via asynchronous calls– XmlHttpRequest (as in ajax)– JSON serialization
• Way faster than XML• Originally decoded with “eval”• Modern browsers provide native encoding /
deconding– JSON.parse(…) / JSON.stringify(…) – Even faster!
– RESTful APIs –WebSockets
• Where supported
And how do we access Data?
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• Faster web sites• Lower traffic• Clear separation– UI– Services / BL
• Enhanced testability– Unit tests for the server API– MVVM in Javascript (e.g. Knockout.js)
• Enhanced portability– E.g. Mobile UI
Great advantages
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• ASP.Net Web API– Comes with MVC4– Provides a new RESTful Web API framework– ODATA support– Very easy– Great IoC support– EF integration (DbDataController<T>)– Can be also installed on MVC3 or Web Forms
• Install-Package AspNetWebApi
• All the ASP.Net Stack is open source!!– http://aspnetwebstack.codeplex.com/
• Alternative: WCF– RESTful support– More control
• Complicated bindings configuration
ASP.Net Web API
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• Use of HTTP verbs:– GET– POST– PUT– DELETE
• Great for CRUD operations• Errors use HTTP semantics– E.g. not found => 404
• Uses custom routing• A lot less bloated than SOAP
RESTful APIs
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
Action HTTP verb Relative URI
Get a list of all products GET /api/products
Get a product by ID GET /api/products/id
Get a product by category GET /api/products?category=category
Create a new product POST /api/products
Update a product PUT /api/products/id
Delete a product DELETE /api/products/id
RESTful APIs example
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
jQuery does all the dirty job, the result is neat and clean:
$.getJSON( "api/products", function(data) { $.each(data, function(index, value) { $("#products").append('<li>' + value.Name + '</li>'); });
});
jQuery example
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
routes.MapHttpRoute( name: "API Default", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional });
• Avoids conflicts with MVC routing• Naming Convention
– GetAllProducts, DeleteProduct, etc
• Explicit action attributes:– [HttpGet], [HttpPost], [HttpPut], [HttpDelete], [NonAction]
• User "api/{controller}/{action}/{id}” for RPC style routing– Needs explicit verb attributes
ASP.Net Web API routing
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• ASP.Net Web API is based on a pipeline• Inherit from DelegatingHandler to
create your handlers– E.g. check an API key
• Add with:– config.MessageHandlers.Add(new
ApiKeyHandler());
HttpMessageHandler
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• Open Data Protocol– A web protocol for querying and updating data
• Enable ODATA queries on your Web API– Just return an IQueriable<T>
• Examples– http://localhost:1702/api/Products?$filter=Enabled
%20eq%20true
– http://localhost:1702/api/Products?$orderby=Name%20desc
– http://localhost:1702/api/Products?$filter=startswith(Name,’whatever')
ODATA + Web API
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• Great tool for troubleshooting
• curl -i -H "Accept: application/json" http://localhost:1823/api/Products
• curl -i -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d @data.json http://localhost:1823/api/Product
CURL
itcampro@ itcamp12# Premium conference on Microsoft technologies
WEB API DEMO
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• A framework that provides some magic for:– Persistent connections
• LongPolling• WebSockets• Examples: chat, stock ticker updates
– Dynamic proxy generation for Javascript code• Hubs
– JSON serialization
• Asynchronous model• Supports self hosting• Unrelated to MVC or Web Forms• Install-package SignalR
– Or: https://github.com/SignalR/SignalR
SignalR
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & DevelopmentLong Polling
1. The client connects via HTTP2. The server waits for available data3. The server sends the response4. Back to step one
A way to simulate push data connections
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
public class MyConnection : PersistentConnection
{ protected override Task OnReceivedAsync(IRequest request, string connectionId, string data) { // Broadcast data to all clients return Connection.Broadcast(data); } }
Routing setup in global.asax:
RouteTable.Routes.MapConnection<MyConnection>("echo", "echo/{*operation}");
Persistent connections (server)
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
$(function () { var connection = $.connection('/echo');
connection.received(function (data) { $('#messages').append('<li>' + data + '</li>'); }); connection.start(); $("#broadcast").click(function () { connection.send($('#msg').val()); }); });
Persistent connections (client)
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• Task OnConnectedAsync(IRequest request, string connectionId)
• Task OnReconnectedAsync(IRequest request, IEnumerable groups, string connectionId)
• Task OnReceivedAsync(IRequest request, string connectionId, string data)
• Task OnDisconnectAsync(string connectionId)
• Task OnErrorAsync(Exception error)
PersistentConnection API
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• Task Broadcast(object value)• Task Send(string signal, object value)
IConnection API
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
var context = GlobalHost.ConnectionManager.GetConnectionContext<MyEndPoint>(); context.Connection.Broadcast(message);
• Useful to send messages starting from a server action
External broadcasts
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
public class Chat : Hub { public void Send(string message) { // Call the addMessage method on all clients Clients.addMessage(message); } }
• Methods can have any name, the client resolves the names via proxy
• Clients is a dynamic object– addMessage is defined in Javascript!!
Hub (server)
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
var chat = $.connection.chat; // Declare a function on the chat hub so the server can invoke it chat.addMessage = function(message) { $('#messages').append('<li>' + message + '</li>'); }; $("#broadcast").click(function () { // Call the chat method on the server chat.send($('#msg').val()) .done(function() { console.log('Success!'); }) .fail(function(e) { console.warn(e); }); }); // Start the connection $.connection.hub.start();
Hub (client)
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• SignalR’s AspNetBootStrapper defines– [assembly:
PreApplicationStartMethod(typeof(AspNetBootstrapper), "Initialize")]
– Initialize calls: RouteTable.Routes.MapHubs();• Mapping the /signalr route
• No need for:– Explicit global.asax route mapping– Web.config settings
Look Mama, no global.asax routes
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>(); context.Clients.say(message);
External broadcasts
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• appcmd.exe set config /section:serverRuntime /appConcurrentRequestLimit:100000
• In %windir%\Microsoft.NET\Framework\v4.0.30319\aspnet.config– maxConcurrentRequestsPerCPU="20000”
• In %windir%\Microsoft.NET\Framework\v4.0.30319\Config\machine.config– <processModel autoConfig="false"
requestQueueLimit="250000" />
IIS setup for high loads
itcampro@ itcamp12# Premium conference on Microsoft technologies
SIGNALR DEMO
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• TCP/IP communication style model– Handshake resembles HTTP
• Interoperable• Standard W3C (still in draft)– Older browsers support old versions
• Bidirectional communications• Supports cross domain access!
WebSockets
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
Request:
GET /mychat HTTP/1.1Host: server.example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==Sec-WebSocket-Protocol: chatSec-WebSocket-Version: 13Origin: http://example.com
Response:
HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=Sec-WebSocket-Protocol: chat
Handshake
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• Url: ws://yourhost/etc– wss: when used with SSL/TLS
var socket = new WebSocket('ws://game.example.com:12010/updates');socket.onopen = function () { setInterval(function() { if (socket.bufferedAmount == 0) socket.send(getUpdateData()); }, 50);};
Javascript
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• IE 10• Chrome 4• Firefox 4• Safari 5• Opera 11
• Server: IIS 8
Minimum requirements
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• Proxies tipically don’t recognize WebSocket traffic
• By using SSL/TLS the problem is mitigated– Client uses HTTP CONNECT in this case
Proxy support
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
IIS 8 – enable WebSockets feature
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & DevelopmentWCF 4.5 – HTTP Activation
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & DevelopmentWCF 4.5
itcampro@ itcamp12# Premium conference on Microsoft technologies
Mobile & Development
• Install-Package Microsoft.WebSockets
RouteTable.Routes.Add(new ServiceRoute("connect", new WebSocketServiceHostFactory(), typeof(GameService)));
public class GameService : WebSocketService { private static GameServer server = new GameServer();
private GameConnection connection;
public override void OnOpen() { string nickname = QueryParameters["nickname"]; int gameSize = int.Parse(QueryParameters["gamesize"]); connection = server.JoinGame(this, nickname, gameSize); }
public override void OnMessage(string message) { connection.ProcessCommand(message); }
protected override void OnClose() { if(connection != null) connection.Disconnect(); } }}
In ASP.Net – updated support
itcampro@ itcamp12# Premium conference on Microsoft technologies
WEBSOCKETS DEMO
itcampro@ itcamp12# Premium conference on Microsoft technologies
Q & A