Skip to content

Instantly share code, notes, and snippets.

@joeriks
Created August 12, 2012 18:47
Show Gist options
  • Save joeriks/3333660 to your computer and use it in GitHub Desktop.
Save joeriks/3333660 to your computer and use it in GitHub Desktop.
Small SignalR + Managedesent sample, tested in WebMatrix (using App_Data), demonstrating using SignalR for "common" client-server calls which are usually done with jquery ajax+url's
Name:
Value:
[add item]
[clear items]
(click on a row to delete it)
NameValues/2: 500 (Second):
NameValues/3: 800 (Third):
NameValues/4: 900 (Fourth):
NameValues/1: 1000 (First):
max : 1000 (First), min : 500 (Second), count : 4
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My Site's Title</title>
<script src="/Scripts/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.signalR-0.5.2.min.js" type="text/javascript"></script>
<script src="/SignalR/hubs" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$.connection.hub.logging = true;
var myHub = $.connection.myHub;
/*
start hub
=> callback to get initial data from server
=> callback to update html document with data
the updateDocument could also be written shorter as
in the examples below
*/
$.connection.hub.start(function () {
myHub.results(function (data) {
updateDocument(data);
});
});
function updateDocument(data) {
var ul = $("#items");
ul.text("");
$("#result").text("");
if (data == null) {
return;
}
/* re-populate list from server data */
$.each(data.items, function (i, dataItem) {
var li = $("<li/>").text(dataItem.Key + ": " + dataItem.Value.Value + " (" + dataItem.Value.Name + "):").data("key", dataItem.Key).appendTo(ul);
});
/* add delete on click */
$("#items li").click(function () {
myHub.removeItem($(this).data("key"), updateDocument);
});
/* show server calculated values */
$("#result").text("max : " + data.max.Value + " (" + data.max.Name + "), min : " + data.min.Value + " (" + data.min.Name + "), count : " + data.count);
}
$("#clear").click(function () {
myHub.clearDictionary(updateDocument);
});
$("#add").click(function () {
var sendName = $("#someName").val();
var sendValue = $("#someValue").val();
/* use client side hub function to call server side */
myHub.addItem({ Name: sendName, Value: sendValue }, updateDocument);
});
});
</script>
</head>
<body>
Name:
<input id="someName" type="text" /><br />
Value:
<input id="someValue" type="text" /><br />
<input id="add" type="button" value="Add item" /><br />
<input id="clear" type="button" value="Clear items" /><br />
<ul id="items">
</ul>
<div id="result"></div>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Web;
using Microsoft.Isam.Esent.Collections.Generic;
using System.Linq;
//
// Install-Package SignalR
// Install-Package ManagedEsent
//
// ManagedEsent stored objects ("PersistentDictionary") needs to be serializable structs afaiu
[Serializable]
public struct NameValue : IComparable<NameValue>
{
public string Name { get; set; }
public int Value { get; set; }
// make it IComparable (just as an experiment)
public int CompareTo(NameValue obj)
{
return Value.CompareTo(obj.Value);
}
}
public class MyHub : SignalR.Hubs.Hub
{
// We keep a separate dictionary for used id's
private static PersistentDictionary<string, int> nextAvailableId =
new PersistentDictionary<string, int>(HttpContext.Current.Server.MapPath("/App_Data/NextAvailableId"));
// Here's the data "storage" dictionary
private static PersistentDictionary<string, NameValue> dictionary =
new PersistentDictionary<string, NameValue>(HttpContext.Current.Server.MapPath("/App_Data/NameValues"));
// incoming data binds from json to NameValue struct by SignalR
public object AddItem(NameValue nameValue)
{
/* store string in persistent dictionary */
dictionary.Add("NameValues/" + getAndConsumeId(), nameValue);
/* return dictionary and some calculations */
return Results();
}
// SignalR json'ifies the returned data automatically:
public object Results()
{
if (dictionary.Count() == 0) return null;
return new
{
min = dictionary.Min(t => t.Value),
max = dictionary.Max(t => t.Value),
count = dictionary.Count(),
items = dictionary.OrderBy(t => t.Value)
};
// We could also use
//Caller.UpdateDocument(new ...);
// to automatically invoke the function on the caller, or even
//Clients.UpdateDocument(new ...);
// to automatically invoke the function on all connected clients
}
private int getAndConsumeId()
{
var dataName = "NameValues";
if (!nextAvailableId.ContainsKey(dataName)) nextAvailableId[dataName] = 0;
var id = nextAvailableId[dataName];
nextAvailableId[dataName] += 1;
return id;
}
public object RemoveItem(string id)
{
if (dictionary.ContainsKey(id)) dictionary.Remove(id);
return Results();
}
public object ClearDictionary()
{
dictionary.Clear();
return Results();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment