ict.ken.be

 

Posts in Category: Javascript

SignalR - Notes 

Categories: .Net Javascript

Real-time Web & Push Services with Hubs
by Christian Weyer (christian.weyer@thinktecture.com)
Developers of SignalR on https://jabbr.net

Push Services pattern (models a service that) 

  • accepts incoming connections from callers
  • is able to push data down to callers
  • abstracts from communication nitty-gritty details
  • consumers send to push service
  • push service notifies consumers
  • external events (Db, Message Queue, ...) trigger push service

HTTP is the protocol

  • Periodic Polling
  • Long Polling (http streaming/comet) -> server only responds when there is data
  • Forever Frame (connection within an iframe)
  • Server-Sent Events (SSE)
  • Web Sockets (only Windows 8/Server 2012, network considerations/blockings)

Hubs

  • public methods are callable from the outside
  • send messages to clients by invoking client-side methods
  • [HubName("chat")]
  • Context holds connection- and request-specific information
  • ConnectionId, Request, Headers, RequestCookies, QueryString, User
  • First register the hubs and then add your other routes.
  • Target method with parameters is dynamically 'injected' into code path, serialized, and embedded into protocol response
  • Groups are not persisted on the server
  • We need to keep track of what connections are in chat groups
  • No automatic group count 
Clients.Caller.newMessage(message);
Clients.Client(Context.ConnectionId).newMessage(message);
Clients.All.newMessage(message);
Clients.Others.newMessage(message);
Clients.AllExcept(Context.ConnectionId).newMessage(message);

Groups.Add(Context.ConnectionId, room);
Clients.Group(room).newMessage(msg);

public override Task OnConnected() {}
public override Task OnDisconnected() {}
public override Task OnReconnected() {}

// Sending data from outside a hub, retrieve hub context via dependency resolver
private void SendMonitorData(string eventType, string connection)
{
var context = GlobalHost.ConnectionManager.GetHubContext<MonitorHub>();
context.Clients.All.newEvent(eventType, connection);
}

Clients

  • .NET4.0+, WinRT, Windows Phone 8, Silverlight 5, jQuery, C++, iOS native, iOS via Mono, Android via Mono
  • /signalr/hubs is the dynamic proxy contract
  • use signalr.exe ghp /url:http://localhost:31373 tool to create a static proxy

Javascript with proxy

 $.connection.hub.logging = true;
chat = $.connection.chat
$.connection.hub.start({ transport:'longPolling' });
$.connection.hub.connectionSlow = onConnectionSlow;

Javascript without proxy

var connection = $.hubConnection();
var proxy = connection.createHubProxy('chat');
proxy.on('newMessage', onNewMessage);
connection.start();
proxy.invoke('sendMessage', $('#message').val());

.Net

var hubConnection = new HubConnection("http://localhost/ps");
var chat = hubConnection.CreateHubProxy("chat");
chat.On<string>("newMessage", msg => messages.Invoke(new Action(() => messages.Items.Add(msg));
hubConnection.Start().Wait();
// Opened, Closed, Error, Received, Reconnected, Reconnecting, StateChanged

Hosting

OWIN (Open Web Server Interface for .Net) - http://owin.org
Katana project - http://katanaproject.codeplex.com

  • Application delegate (AppFunc) var AppFunc = Func<IDictionary<string, object>, Task>;
  • Environment dictionary
  • ASP.Net hosting sits on top of OWIN
  • Self-hosting
  • Microsoft.Owin.Hosting aka Katana
  • Microsoft.Owin.Host.HttpListener
// process user needs http.sys permissions on the url namespace
public void Configuration(IAppBuilder app)
{
var a = Assembly.LoadFrom("Services.dll");
app.MapHubs(new HubConfiguration { EnableCrossDomain = true });
}

using(WebApplication.Start<Startup>("http://localhost:6789")
{
Console.WriteLine("Hubs running...");
Console.ReadLine();
}

// jQuery client needs to explicitly set connection url
$.connection.hub.url = "http://localhost:6789/signalr";

Azure

  • Which server instance handles the client request?
  • Which instance pushes?

Other aspects

  • Use SignalR message bus
  • SignalR extensible architecture
  • Persistent connections
  • Scale-Out
  • WebApi Integration
  • Security

Javascript debounce vs throttle function 

Categories: Javascript

Debounce is often confused with throttle, mainly because some frameworks like knockout use the wrong naming... not that it matters much, but here you can see the difference in code.

Debounce (fire after pause)

function debounce(fn, delay) {
  var timer = null;
  return function () {
    var context = this, args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function () {
      fn.apply(context, args);
    }, delay);
  };
}
$('input.search').keypress(debounce(function (event) {
  // do the ajax call
}, 250));

Throttle (keep firing with pauses)

function throttle(fn, threshhold, scope) {
  threshhold || (threshhold = 250);
  var last, deferTimer;
  return function () {
    var context = scope || this;
    var now = +new Date, args = arguments;
    if (last && now < last + threshhold) {
      // hold on to it
      clearTimeout(deferTimer);
      deferTimer = setTimeout(function () {
        last = now;
        fn.apply(context, args);
      }, threshhold);
    } else {
      last = now;
      fn.apply(context, args);
    }
  };
}
$('body').on('mousemove', throttle(function (event) {
  console.log('tick');
}, 1000));

Breeze and OData case sensitive 

Categories: Javascript

When using Breezejs with OData you have to keep in mind that the contains filter is case sensitive. This is because the OData standard is case sensitive. Which might seem ridiculous at first, but going from case sensitive into case insensitve is easier then the other way around. Anyway here is the solution for those who make search boxes case insensitive like the rest of us.

var query = breeze.EntityQuery.from('SearchView');
query = query.where("tolower(Description)", breeze.FilterQueryOp.Contains, filterOptions.filterText.toLowerCase());
manager.executeQuery(query).then(querySuccess).fail(queryFailed);

Rich Data 

Categories: Javascript

Why Rich Data ?

Because UX (user experience) is king, and because we do so much more in real applications then getting data and displaying it.

What is Rich Data ?

  • Client caching is possible becuse of using a DataContext on the client
  • Change tracking on the entities
  • Queries both local and from servers by using OData filters
  • Extend the models, cause some thing we do not need to persist to the server.
  • Object graphs cause we all have Customer, Orders, OrderDetails (or we are not making money) and we would love to associate then when we allready know about them on the client.

Some notes about rich data from LIDNUG live meeting

Lidnug & John Papa: Building Single Page Apps
Event: Single Page Apps Jump-Start
Hosted by: Linked In .NET User Group
When: Thursday Novemeber 15th, 2012 at 1:00pm EST to 2:30 pm EST (19u belgium)
357 people - 25 questions (over 100 didn't stay for questions, dumb)
 
Code Camper JumpStart Breeze 101
  • Reduced javascript data handling code 1200 lines to about 170 lines with more functionality.
  • Upshotjs is no longer in active development.
  • With BreezeJs, AmplifyJs is no longer needed for local storage.
  • Validation is possible but you can also use knockout validation.
  • Was using a lot of knockout mapping before, but not anymore.
var query = EntityQuery.from('Speakers').orderBy('lastName, firstName');
return manager.executeQuery(query).then(querySucceeded).fail(queryFailed);
function querySucceeded(data) {
speakers(data.results);
}
  • The http://www.asp.net/vnext/overview/fall-2012-update update build of asp.net includes a single page application template, but does not yet include rich data. (select mvc4 first and then you will see the SPA template, else use devenv.exe /InstallVSTemplates)
  • Best is to try to load as much data at first load, but only if it is common used data.
  • On the roadmap are using Breezejs together with SignalR, so we can broadcast to the clients to refresh.
  • SPA for applications with more then 200 views ? Is this possible? Maybe better to split them up in smaller applications.
  • For stock applications and more 5000 operations per second you need signalr with sockets!
  • John Papa will release a tutorial on Typescript early december.
  • Likes knockout templates, only the others if really a lot of elements. Using mustache for speed.
  • http://www.youtube.com/user/lidnug

Live Meeting about single page applications

Upshotjs alternatives 

Categories: Javascript

Some months ago Brad Severtson gave use some nice rich data examples using MVC 4 beta and Upshot.js, unfortunatelly the current asp.net roadmap put this in the fridge. Which kind of makes sense because there are already two big open-project doing something similar. The code is still available and I think their implementation of a DbController wrapper around the web.api is sweet and I am going to keep for the moment. As alternative to Upshot.js I will switch to Breeze, mainly because it is endorsed by John Papa. (and yes I know he is friends with Ward from Breeze). Edit: I am currently trying out JayData more, it seems more complete then Breezejs. Edit 2: it's now july 2013 and I am using Breezejs together with Angularjs in production for most of my mojoPortal sites.

The alternatives to Upshot.js 

There are also some other small libraries, but I think they will disappear. (Data.js from the Asp.Net OData team, KnockoutSPA, SPA.js, ...)

Maybe you got here because of the following error (using upshot beta with the mvc4 rc does not work):

Method not found: 'Void System.Net.Http.Headers.HttpHeaders.AddWithoutValidation(System.String, System.Collections.Generic.IEnumerable`1<System.String>)'.

 

Page 2 of 4 << < 1 2 3 4 > >>