Fleck.Extended

Why?

When I started to consume Fleck it just lacked some of the features (which is also what I like about Fleck, it’s simple and bare bone and easy to get started with) I wanted and I also wasn’t sure I would go with Fleck, so I created a small layer sitting on top of Fleck.

Continue reading

Some XSockets and SisoDb fun – Part 2 of 2

This is a continuation of Some XSockets and SisoDb fun – Part 1 of 2 which more was about getting started with XSockets.Net. This post is about putting SisoDb to use. The steps we will go through are:

Get the Code

The code is located at GitHub. Both the SisoDbClient.Js and a sample app matching the sample we will create here.

  • Step 1 – Create a model
  • Step 2 – Inserts – Add support to the socket handler
  • Step 3 – Inserts – Hook up the UI
  • Step 4 – GetById – Add support to the socket handler
  • Step 5 – GetById – Hook up the UI
  • Step 6 – Updates – Add support to the socket handler
  • Step 7 – Updates – Hook up the UI
  • Step 8 – Queries – Add support to the socket handler
  • Step 9 – Queries – Hook up the UI
  • Step 10 – DeleteById – Add support to the socket handler
  • Step 11 – DeleteById – Hook up the UI

Step 1 – Create a model

First of, we need a simple model to work with. Create a class library project named “Model” and add the following class:

public class Article
{
    public Guid ArticleId { get; set; }
    public int PLU { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

Now, it’s time to extend our socket handler to support inserts of the newly created model.

Step 2 – Inserts – Add support to the socket handler

It’s time to start using SisoDb and we will now make the handler support inserts. But to do that we will need to setup some plumbing, which of course, also will be used for updates, deletes and queries. Now, lets install the “SisoDb core package” to the “XSocketHandler” project.

To support dynamic lambda expression when querying, we also need the “SisoDb.Dynamic” package so install that to.

Now, lets create the shell method accepting inserts. Add this to the “SisoDbHandler” class in the “XSocketHandler” project:

[HandlerEvent("Insert")]
public void Insert(InsertCommand command)
{
    //Use SisoDb, but resolve it via a configurable Runtime class.
}

Instead of locking down our handler to a specific provider of SisoDb, we will configure this in the application entry point instead, more precisely, in the “Server”. But before that, create a new class-library project named “Core”.

Now, install the “SisoDb core package” to this project as well.

The Core project will define a “Runtime” class that holds some resources that we will consume in our handler. This is a quick solution/hack and you would probably do it another way. Perhaps using MEF or some IoC-container framework. But lets keep it fairly simple. Add a new class called “Runtime” to the “Core project”.

public static class Runtime
{
    public static IResources Resources { get; set; }
}

We need to be able to resolve a ISisoDatabase and, given a type name, locate a certain structure/entity type. Lets define two simple Funcs for this.

public interface IResources
{
    Func<ISisoDatabase> DbResolver { get; set; }
    Func<string, Type> StructureTypeResolver{ get; set; } 
}

Lets initialize the Runtime. Install a specific SisoDb provider into your Server project. I will choose the Sql2012 provider.

To support dynamic lambda expression when querying, we also need the “SisoDb.Dynamic” package so install that to.

Add a class called “Resources” to the Server project and setup the two Func members that resolves a Db and Structure types. NOTE! The ISisoDatabase should be kept long lived since it contains caches of e.g Db-Schemas.

public class Resources : IResources
{
    private readonly ISisoDatabase _db;
    private readonly IDictionary<string, Type> _structureTypes;

    public Func<ISisoDatabase> DbResolver { get; set; }
    public Func<string, Type> StructureTypeResolver{ get; set; }

    public Resources()
    {
        //Func should resolve the SAME ISisoDatabase each time
        //Demo is the name of the connection string in App.Config
        _db = "Demo".CreateSql2012Db();
        _db.CreateIfNotExists();
        DbResolver = () => _db;

        //Simple key-value map for acceptable structure types
        _entityTypes = GetEntityTypes().ToDictionary(t => t.Name);
        StructureTypeResolver= name => _structureTypes[name];
    }

    private IEnumerable<Type> GetStructureTypes()
    {
        //This determines what Entities/Structures that will be accessible
        yield return typeof (Article);
    }
}

Now, assign an instance of the Resource class to the Runtime

static void Main(string[] args)
{
    Runtime.Resources = new Resources();
    //...
    //leave the rest untouched
    //...
}

Add a connection string to the App.Config in the Server project.

<connectionStrings>
  <add name="Demo" connectionString=
       "data source=.;initial catalog=Demo;integrated secuirty=true;"/>
</connectionStrings>

Now, lets fix the handler. I couldn’t get a constructor with arguments to work so we will resolve the Db inside it. Add a default constructor to the “SisoDbHandler” and resolve a Db to be used:

public class SisoDbHandler : XBaseSocket
{
    private readonly ISisoDatabase _db;

    public SisoDbHandler()
    {
        _db = Runtime.Resources.DbResolver();
    }

    //...
    //leave the rest untouched
    //...

Almost there. Fix the Insert method:

[HandlerEvent("Insert")]
public void Insert(InsertCommand command)
{
    var structureType = Runtime
        .Resources
        .StructureTypeResolver(command.StructureName);

    var result = new InsertResult
    {
        StructureName = command.StructureName,
        Json = _db.UseOnceTo().InsertJson(structureType, command.Json)
    };

    this.AsyncSend(result, "OnInserted");
}

The last steps that are missing is to create the “InsertCommand” and the “InsertResult”. Lets add them.

//Namespace: XSocketHandler.Commands
public class InsertCommand
{
    public string StructureName { get; set; }
    public string Json { get; set; }
}
//Namespace: XSocketHandler.Results
public class InsertResult
{
    public string StructureName { get; set; }
    public string Json { get; set; }
}

Our handler is now ready to serve insert calls. Lets consume it.

Step 3 – Inserts – Hook up the UI

The next step is to update our demo.html page and make it use the insert method. This is what we will start out from, with just a few minor adjustments from the previous post:

<!DOCTYPE html>
<html>
<head>
    <title>Demo - SisoDb-XSockets</title>
    <script src="Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
    <script src="Scripts/JXSockets-1.0.4.beta.js" type="text/javascript"></script>
    <script src="http://cloud.github.com/downloads/danielwertheim/
                 SisoDb-XSockets/sisodbclient-debug-v0.3.0.js" 
            type="text/javascript"></script>
        
    <script type="text/javascript">
        var my = {};

        $(function () {
            //Hook up client
            my.client = new SisoDbClient("ws://127.0.0.1:4502/SisoDbHandler");
            my.client.logger.enabled = true;
            my.client.connect();

            //Hookup UI to consume client
            $("#ping button").on("click", function () {
                my.client.ping($("#ping_message").val());
            });

            //Hookup listeners
            my.client.onPinged(function (data) {
                my.dumpResult("onPinged", data.Message);
            });

            //Some helpers
            my.dumpResult = function (action, result) {
                $("<li>").addClass(action)
                         .text(result)
                         .appendTo(".outputs ul:eq(1)");
            };
        });
    </script>
    <link href="Content/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <section class="inputs">
        <fieldset id="ping">
            <legend>Ping</legend>
            <label for="ping_message">Message</label>
            <input type="text" id="ping_message" placeholder="Message" />
            <button>Ping</button>
        </fieldset>
    </section>
    <section class="outputs">
        <ul>
            <li class="onPinged description">Ping result</li>
            <li class="onInserted description">Insert result</li>
            <li class="onDeletedById description">Delete by id result</li>
            <li class="onGetById description">Get by id result</li>
            <li class="onQuery description">Query result</li>
            <li class="onUpdated description">Update result</li>
        </ul>
        <ul></ul>
    </section>
</body>
</html>

First add a new Fieldset below the one for Ping.

<fieldset id="article_insert">
    <legend>Insert</legend>
    <div class="form-item">
        <label for="article_insert_name">Name</label>
        <input type="text" id="article_insert_name" placeholder="Name" />
    </div>
    <div class="form-item">
        <label for="article_insert_plu">PLU</label>
        <input type="text" id="article_insert_plu" placeholder="PLU" />
    </div>
    <div class="form-item">
        <label for="article_insert_price">Price</label>
        <input type="text" id="article_insert_price" placeholder="Price" />
    </div>
    <div class="form-actions">
        <button class="insert">Insert</button>
    </div>
</fieldset>

Now we need to make the UI invoke the socket handler when we click on Insert.

$(".inputs #article_insert .insert").on("click", function () {
    my.client.insert("Article", {
        Name: $("#article_insert_name").val(),
        PLU: $("#article_insert_plu").val(),
        Price: $("#article_insert_price").val()
    });
});

We also want to react on whenever an item is inserted, so lets hook that up:

my.client.onInserted(function (data) {
    my.dumpResult("onInserted", data.Json);
});

Now, fire up the Server and the MVC application and visit the demo.html page. Below I have tried the Ping operation and made a simple insert.

Step 4 – GetById – Add support to the socket handler

This time, most of the plumbing is already in place in the handler. Lets add GetById:

[HandlerEvent("GetById")]
public void GetById(GetByIdCommand command)
{
    var structureType = Runtime
        .Resources
        .StructureTypeResolver(command.StructureName);
    var structureSchema = GetStructureSchema(structureType);

    var id = ConvertId(command.Id, structureSchema);
    var result = new GetByIdResult
    {
        StructureName = command.StructureName,
        Id = command.Id,
        Json = _db.UseOnceTo().GetByIdAsJson(structureType, id)
     };

     this.AsyncSend(result, "OnGetById");
}

The above code needs two helper methods:

private IStructureSchema GetStructureSchema(Type structureType)
{
    return _db.StructureSchemas.GetSchema(structureType);
}

private static object ConvertId(string id, IStructureSchema structureSchema)
{
    return StructureId.Create(id, structureSchema.IdAccessor.IdType).Value;
}

Now, lets finish the GetById support in the handler. Add the GetByIdCommand and GetByIdResult.

//Namespace: XSocketHandler.Commands
public class GetByIdCommand
{
    public string StructureName { get; set; }
    public string Id { get; set; }
}
//Namespace: XSocketHandler.Results
public class GetByIdResult
{
    public string StructureName { get; set; }
    public string Id { get; set; }
    public string Json { get; set; }
}

Step 5 – GetById – Hook up the UI

Time to make the UI support the GetById operation. First add a new FieldSet that lets you enter an Id to return an item for.

<fieldset id="article_getById">
    <legend>Get by Id</legend>
    <div class="form-item">
        <label for="article_getById_id">Id</label>
        <input id="article_getById_id" type="text" placeholder="id"/>
    </div>
    <div class="form-actions">
        <button class="get">Get</button>
    </div>
</fieldset>

Make the UI invoke the handler:

$(".inputs #article_getById .get").on("click", function () {
    my.client.getById("Article", $("#article_getById_id").val());
});

Now, hook up the UI to react on the result of the GetByIdCommand.

my.client.onGetById(function (data) {
    my.dumpResult("onGetById", data.Json);
});

You should now be able to perform GetById operations, which will look like this:

Step 6 – Updates – Add support to the socket handler

Time to fix Updates. Add this to the handler:

[HandlerEvent("Update")]
public void Update(UpdateCommand command)
{
    var structureType = Runtime.Resources.StructureTypeResolver(command.StructureName);
    var structure = _db.Serializer.Deserialize(structureType, command.Json);
    var structureSchema = GetStructureSchema(structureType);

    _db.UseOnceTo().Update(structureType, structure);
            
    var result = new UpdateResult
    {
        StructureName = command.StructureName,
        Id = structureSchema.IdAccessor.GetValue(structure).Value.ToString()
    };

    this.AsyncSend(result, "OnUpdated");
}

Also add the UpdateCommand and the UpdateResult.

//Namespace: XSocketHandler.Commands
public class UpdateCommand
{
    public string StructureName { get; set; }
    public string Json { get; set; }
}
//Namespace: XSocketHandler.Results
public class UpdateResult
{
    public string StructureName { get; set; }
    public string Id { get; set; }
}

Step 7 – Updates – Hook up the UI

Time to make the UI support the Update operation. First add a new FieldSet that lets you enter an Id to load an item for. Then some controls that lets you update the values.

<fieldset id="article_update">
    <legend>Update - Load</legend>
    <div class="form-item">
        <label for="article_update_id">Id</label>
        <input id="article_update_id" type="text" placeholder="id"/>
    </div>
    <div class="form-actions">
        <button class="load">Load</button>
    </div>

    <legend>Update - Save</legend>
    <div class="form-item">
        <label for="article_update_name">Name</label>
        <input type="text" id="article_update_name" placeholder="Name" />
    </div>
    <div class="form-item">
        <label for="article_update_plu">PLU</label>
        <input type="text" id="article_update_plu" placeholder="PLU" />
    </div>
    <div class="form-item">
        <label for="article_update_price">Price</label>
        <input type="text" id="article_update_price" placeholder="Price" />
    </div>
    <div class="form-actions">
        <button class="update">Update</button>
    </div>
</fieldset>

Make the UI invoke the handler:

$(".inputs #article_update .load").on("click", function () {
    my.client.getById("Article", $("#article_update_id").val());
});

$(".inputs #article_update .update").on("click", function () {
    my.client.update("Article", {
        ArticleId: $("#article_update_id").val(),
        Name: $("#article_update_name").val(),
        PLU: $("#article_update_plu").val(),
        Price: $("#article_update_price").val()
    });
});

Now, extend the “onGetById callback”, since it now could represent either “GetById” or “Load”.

my.client.onGetById(function (data) {
    if ($("#article_update_id").val()) {
        var doc = JSON.parse(data.Json);
        $("#article_update_name").val(doc.Name);
        $("#article_update_plu").val(doc.PLU);
        $("#article_update_price").val(doc.Price);
    }
    else
        my.dumpResult("onGetById", data.Json);
});

Also hook up the “onUpdated callback”:

my.client.onUpdated(function (data) {
    my.dumpResult("onUpdated", data.Id.toString());
});

You should now be able to perform Update operations, which will look like this:

Step 8 – Queries – Add support to the socket handler

Time to fix Queries. Add this to the handler:

using SisoDb.Dynamic; //IMPORTANT! IMPORTANT! IMPORTANT!

[HandlerEvent("Query")]
public void Query(QueryCommand command)
{
    var structureType = Runtime
        .Resources
        .StructureTypeResolver(command.StructureName);
            
    var result = new QueryResult
    {
        StructureName = command.StructureName
    };

    using (var session = _db.BeginSession())
    {
        result.Json = session.Query(structureType).Where(command.Predicate).ToArrayOfJson();
    }

    this.AsyncSend(result, "OnQuery");
}

Also add the QueryCommand and the QueryResult.

//Namespace: XSocketHandler.Commands
public class QueryCommand
{
    public string StructureName { get; set; }
    public string Predicate { get; set; }
}
//Namespace: XSocketHandler.Results
public class QueryResult
{
    public string StructureName { get; set; }
    public string[] Json { get; set; }
}

Step 9 – Queries – Hook up the UI

Time to make the UI support Queries with lambda style syntax. First add a new FieldSet that lets you enter a query.

<fieldset id="article_query">
    <legend>Query</legend>
    <div class="form-item">
        <label for="article_query_predicate">Predicate</label>
        <input id="article_query_predicate" type="text" placeholder="predicate"/>
    </div>
    <div class="form-actions">
        <button class="query">Query</button>
    </div>
</fieldset>

Make the UI invoke the handler:

$(".inputs #article_query .query").on("click", function () {
    my.client.query("Article", $("#article_query_predicate").val());
});

Hook up the UI to display the query result for the “onQuery callback”.

my.client.onQuery(function (data) {
    $.each(data.Json, function (i, e) {
        my.dumpResult("onQuery", e);
    });
});

You should now be able to perform queries using syntax like "x => x.PLU >= 100"

Step 10 – DeleteById – Add support to the socket handler

Time to fix DeleteById. Add this to the handler:

[HandlerEvent("DeleteById")]
public void DeleteById(DeleteByIdCommand command)
{
    var structureType = Runtime
        .Resources
        .StructureTypeResolver(command.StructureName);
    var structureSchema = GetStructureSchema(structureType);

    var id = ConvertId(command.Id, structureSchema);

    _db.UseOnceTo().DeleteById(structureType, id);

    var result = new DeleteByIdResult
    {
        StructureName = command.StructureName,
        Id = command.Id
    };

    this.AsyncSend(result, "OnDeletedById");
}

Also add the DeleteByIdCommand and the DeleteByIdResult.

//Namespace: XSocketHandler.Commands
public class DeleteByIdCommand
{
    public string StructureName { get; set; }
    public string Id { get; set; }
}
//Namespace: XSocketHandler.Results
public class DeleteByIdResult
{
    public string StructureName { get; set; }
    public string Id { get; set; }
}

Step 11 – DeleteById – Hook up the UI

Again, lets just add some simple controls to allow you to enter an Id to delete.

<fieldset id="article_deleteById">
    <legend>Delete by Id</legend>
    <div class="form-item">
        <label for="article_deleteById_id">Id</label>
        <input id="article_deleteById_id" type="text" placeholder="id"/>
    </div>
    <div class="form-actions">
        <button class="delete">Delete</button>
    </div>
</fieldset>

Make the UI invoke the handler:

$(".inputs #article_deleteById .delete").on("click", function () {
    my.client.deleteById("Article", $("#article_deleteById_id").val());
});

Now, hook up the UI to react on the result of the GetByIdCommand.

my.client.onDeletedById(function (data) {
    my.dumpResult("onDeletedById", data.Id.toString());
});

You should now be able to perform DeleteById operations, which will look like this:

The SisoDbClient.Js

The client is using the XSockets.JsApi and is written using CoffeeScript. It’s not large, have a look at it on GitHub.

Where to go from here

The code is hosted on GitHub. Both the SisoDbClient.Js (which is authored using CoffeeScript) and the XSocketHandler. If this looks interesting, pull it down and extend the code yourself. E.g adding exception handling, but as of now, I have nothing more to cover in this post. Happy coding!

//Daniel

Some XSockets and SisoDb fun – Part 1 of 2

This is a two post series that will show you how to use XSockets and SisoDb to create a JavaScript client for SisoDb, that let’s you consume the db directly from JavaScript. Not saying it’s what you should do, just showing what you can do. In this first post we will look at getting started with XSockets and getting our custom handler in place. The next post will show the implementation. The steps in this post are:

  • Step 1 – Setup XSockets
  • Step 2 – Create the SisoDbHandler
  • Step 3 – Create a debuggable server
  • Step 4 – Implement a simple Ping method in our SisoDbHandler
  • Step 5 – Use the SisoDbClient.js to invoke our Ping member

Step 1 – Setup XSockets

First create a new empty ASP.Net MVC 3 project. Then install the NuGet package XSockets. Note! Use the Package Manager console

After the installation is done, some scaffolding templates (located under CodeTemplates) has been installed along with a XSocket-server and some web samples (located under XSockets). There’s also a new project “XSocketHandler” which is empty at the moment. This is where we will put our “SisoDbHandler“.

The development server will represent the server endpoint serving client connections. The client connection could come from e.g a JavaScript client using the XSockets.JsApi package or from .Net code using XSockets.External.

Now, lets start the development server via Windows explorer; and have a look at some of it’s commands. Start it and type: “help“.

The commands, currently available, are:

Try the “handlers” command. It will list the currently available handlers. And per default there’s one serving textual data (e.g JSON) and one serving binary data. And when we are done there will be a “SisoDbHandler“.

The included GenericText and GenericBinary handlers will let you, out of the box, be able to get up an running pushing JSON messages around and stream binary data. Hence you could e.g. create chats etc, right out of the box. Have a look at the included examples to see how easy it is.

Step 2 – Create the SisoDbHandler

A handler could be seen as a controller in ASP.Net MVC; and each handler serves one or many requests. To create a handler, turn back to the Package Manager Console and use the “scaffold” command and select “XSocketHandler“.

Name it: “SisoDbHandler“.

This will scaffold a new XSocketHandler named “SisoDbHandler” in the XSocketHandler project. Compile the solution and use “Show all files” in the MVC project, and you will see that the build events of the XSocketHandler project have copied the “XSocketHandler.dll” to the “XSocketServerPlugins” folder.

Now, start the server again and run the “handlers” command. You should now see the new “SisoDbHandler“.

Step 3 – Create a debuggable server

To be able to easily debug our handler and to manage deployment of dependencies during development, we will create a custom Server and not use the precompiled server under the MVC project.

Add a new console project. Name it “Server” and remove client profile for it (I wrote a quick post about how to get rid of it for-ever in about 5minutes.

Now, copy everything inside the folder “$MVCApp$\XSockets\DevelopmentServer” to “$Solution$\XSockets” and rename “XSocketServerPlugins” to “Plugins“. Clean it up so that it looks like this:

Add a reference to the “XSockets.Core.dll” above in the Server project.

Now, add an App.Config to the newly created Server-project. Copy the contents of “$MVCApp$\\XSockets\DevelopmentServer\XSockets.DevelopmentServer.Console.exe.config” to your newly created App.config file.

Locate the app-setting “XSocketServerPluginCatalog” and make it look like this:

<add key="XSocketServerPluginCatalog" value="..\..\..\XSockets\Plugins\" />

Go to the XSocketHandler project and open properties for it. Adjust the Pre- and Post- build events so that the dll gets copied to the Server-project instead.

Pre-build event

IF NOT EXIST "$(SolutionDir)XSockets\Plugins\" mkdir "$(SolutionDir)XSockets\Plugins\"

Post-build event

copy "$(TargetDir)$(TargetName).dll", "$(SolutionDir)XSockets\Plugins\"
copy "$(TargetDir)$(TargetName).pdb", "$(SolutionDir)XSockets\Plugins\"

Create a class Named “Start” under the Server-project. Copy the content from “MVC-Project\XSockets\devservercode.txt” to this newly created class. Fix namespaces and add reference to the “Server\XSockets\XSockets.Core.dll“. You will also need to add references to “System.Componentmodel.Composition“. The namespaces and using statements should look like this:

using System;
using System.ComponentModel.Composition;
using System.Configuration;
using XSockets.Core.Plugin.MEF;
using XSockets.Core.XSocket.Interface;

namespace Server
{
    public class Start : Composable
    {
        //... ... ...
    }
}

It’s time for the final adjustment. Now lets fix Program.cs. In $MVCApp$\XSockets\DevelopmentServer\HOW_DO_I_DEBUG_MY_HANDLERS.txt you can find a snippet around step 7 in that file. Make the Main method look something like this:

static void Main(string[] args)
{
    try
    {
        new Start();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        if (ex.InnerException != null)
            Console.WriteLine(ex.InnerException.Message);
        Console.ReadLine();
    }
}

It should now be ready to serve our client requests. Fire up the Server and run the “handlers” command and ensure that the “SisoDbHandler” is located in there.

Step 4 – Implement a simple Ping method in our SisoDbHandler

Before wrapping this up, let’s add a simple Ping action in our handler. Again, a handler could be seen as a controller in Asp.Net MVC; and it’s members serving socket calls; could be seen as actions in Asp.Net MVC.

Create a new folder/namespace, and call it “Commands“. Add a class called “PingCommand“. This will serve as our model in.

public interface ICommand {}

public class PingCommand : ICommand
{
    public string Message { get; set; }
}

Create a new folder/namespace, and call it “Results“. Add a class called “PingResult“. This will serve as our model out.

public interface IResult {}

public class PingResult : IResult
{
    public string Message { get; set; }
}

Now, add a member in our SisoDbHandler, and make it look like this:

[HandlerEvent("Ping")]
public void Ping(PingCommand command)
{
    this.AsyncSend(new PingResult { Message = command.Message }, "OnPinged");
}

If you now start the Server and run the “handlers” command, you will see that the SisoDbHandler now accepts calls to a member called “Ping“.

Step 5 – Use the SisoDbClient.js to invoke our Ping member

Now, lets use the added Ping member. Create a simple html-page in the root of our MVC-app. Name it “demo.html“. We need script references to jQuery, XSockets and the SisoDbClient.js libs.

<!DOCTYPE html>
<html>
<head>
	<title>Demo - SisoDb-XSockets</title>
	<script src="Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
	<script src="Scripts/JXSockets-1.0.4.beta.js" type="text/javascript"></script>
	<script src="http://cloud.github.com/downloads/danielwertheim/SisoDb-XSockets/sisodbclient-debug-v0.1.0.js" type="text/javascript"></script>
	
	<script type="text/javascript">
		var my = {};

		$(function () {
			//Hook up client
			my.client = new SisoDbClient("ws://127.0.0.1:4502/SisoDbHandler");
			my.client.logger.enabled = true;
			my.client.connect();

			//Hookup listeners
			my.client.onPinged(function (data) {
				$("<li>").text(data.Message).prependTo("ul:first");
			});

			//Hookup UI to consume client
			$("#ping").on("click", function () {
				my.client.ping($("#pingMessage").val());
			});
		});
	</script>
	<link href="Content/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
	<fieldset>
		<legend>Ping</legend>
		<label for="pingMessage">Message</label>
		<input type="text" id="pingMessage"/>
		<button id="ping">Ping</button>
	</fieldset>
	
	<ul></ul>
</body>
</html>

Now, start the server and start the MVC-app and browse to the Html-page. Run the command “status” in the server and you should see something like this:

Lets invoke our UI and just send the text: “Test“. If you have the console running, the SisoDbClient.Js will output some logging. You can turn this off by changing this line:

my.client.logger.enabled = false;

That’s it! The next time we will implement a simple model and the CRUD operations.

//Daniel