Posts Tagged ‘Meteor’
Meteor as a persistence layer
The idea of considering Meteor as a persistence layer might be crazy. But there is a good reason for doing that, the real time pushing of data to connected clients using Distribute Data Protocol. Then why cant we write the entire application in Meteor including the User interface, yes we can Meteor supports it. But some people have preference or every one might not be comfortable in creating stunning UI in Meteor but good in ASP.NET. So how do we bridge the best of both the worlds. Let’s take a look at it.
Let’s think about an online Cricket score board, what are all the components we might have
-
A score feeder, a deamon that gets the score from a REST Api or a web service and updates to database.
-
A web app that fetches the data and present it to the user.
The issue here is to get the updated score the user needs to refresh the page. What if user gets the data in real time without doing any page refresh. Let’s see how to add these kind of features.
Here the UI will be in ASP.NET and the DDP client library is DDPClient.NET and for real time signalling of data to connected client, we can use SignalR. DDPClient.NET is integrated with SignalR.
Let’s have a look at how DDPClient.NET can be used in this scenario to push data to connected clients. In one of my previous post I explained a bit detail about DDPClient.NET. Recently I added SignalR framework to it to extend DDPClient accessible from any type of application, be it an ASP.NET or Javascript app or Windows Phone or Desktop app that can act as SignalR Client.
Rest of the post we will see how to receive real time updates from Meteor server using DDPClient.NET.
Right now in DDPClient.NET, SignalR uses self hosting approach. Let’s see how to start the DDPClient.NET, for test I hosted it in a console application.
class Program { static void Main(string[] args) { DDPClientHost host = new DDPClientHost("http://localhost:8081/", "localhost:3000"); host.Start(); Console.ReadLine(); } }
DDPClientHost take two parameters the first one is, in which URL DDPClient.NET should listen for incoming request, the second one is to specify where Meteor server is running. Then just call the Start function in the DDPClientHost instance. That’s it, now DDPClient.NET is ready to receive incoming request.
ASP.NET Javascript client
Let’s see how to subscribe to a Meteor’s published item from a javascript client.
$(function () { var connection = $.hubConnection('http://localhost:8081/'); proxy = connection.createProxy('DDPStream') connection.start() .done(function () { proxy.invoke('subscribe', 'allproducts','product'); $('#messages').append('<li>invoked subscribe</li>'); }) .fail(function () { alert("Could not Connect!"); }); proxy.on('flush', function (msg) { $('#messages').append('<li>' + msg.prodName + '</li>'); }); });
Let’s do a quick walkthrough of the code. As you can see
- The hubÇonnection should point to the url where DDPClient.NET is listening.
- The proxy should be created for DDPStream, it’s a SignalR Hub and is mandatory to use the same name.
-
Once the connection started successfully, we should invoke the Subscribe function declared in DDPStream hub with the published item name declared in Meteor. we should also pass the name of the Collection it returns, in this case it returns a collection of Product. If in case the Meteor’s published item name and the collection name is same then we can simply write proxy.invoke(‘subscribe’, ‘product’); You don’t have to pass the collection name’.
See the code below to see how to publish item from Meteor Server.
Meteor.publish("allproducts", function () { return Products.find(); });Products is a Meteor’s collection that returns Product
Products = new Meteor.Collection("product");
-
Also we should have a function called Flush as shown below. This function will called by the DDPStream to send the data to the connected clients.
proxy.on('flush', function (msg) { $('#messages').append('<li>' + msg.prodName + '</li>'); });
Desktop/Console Application client
It’s similar to the code shown above but it will in C#. See the code below.
class Program { static void Main(string[] args) { var hubConnection = new HubConnection("http://localhost:8081/"); var ddpStream = hubConnection.CreateProxy("DDPStream"); ddpStream.On("flush", message => System.Console.WriteLine(message.prodName)); hubConnection.Start().Wait(); ddpStream.Invoke("Subscribe", "allproducts","product"); System.Console.Read(); } }
That’s it we are done. Now any insert or update of data to the product collection will get notified instantly to all the connected clients. If you run the application you can see the ASP.NET page will show any newly added product without refreshing the page. The DDPClient.NET is still in development.
You can download DDPClient.NET and the example from Github.
Happy coding…
DDPClient.NET–.NET client for Meteor’s Distributed Data Protocol
Last couple of hours I was working on a small .NET client library to connect to Meteor js application using Distributed Data Protocol (DDP). This post will give some insight to the library I am working on. You can see more details of DDP here.
Using DDPClient.NET you can subscribe to published items or call a Meteor method and display the same in your ASP.NET or Desktop applications.
First let’s go through the server code in my meteor application.
if(Meteor.is_server) { Meteor.publish("allproducts", function(){ return Products.find(); });
Meteor.startup(function(){ console.log("starting Point of sale application....."); }); Meteor.methods({ addProduct: function (prodCode, prodDesc) { return "Product Name: " + prodDesc + " Product Code: " + prodCode; }
}); }
From the Meteor application we are publishing an item called ‘allproducts’ and have a server method called ‘addProduct’ that takes two parameters. Now let’s see how to subscribe to published item and call the server method using DDPClient.NET.
Subscribe to Published items
class Program { static void Main(string[] args) { IDataSubscriber subscriber = new Subscriber(); DDPClient client = new DDPClient(subscriber); client.Connect("localhost:3000"); client.Subscribe("allproducts"); } }
public class Subscriber:IDataSubscriber { public void DataReceived(dynamic data) { try { if (data.type == "sub") { Console.WriteLine(data.prodCode + ": " + data.prodName +
": collection: " + data.collection); } } catch(Exception ex) { throw; } } }
As you can see it’s very easy to connect to Meteor application using DDPClient.NET. Just call the Connection function with the url. Then call the subscribe function to subscribe to any published item in Meteor application.
In the above code I subscribed to ‘allproducts’ item. After you subscribed successfully to the meteor application, we will receive all the products stored in the db. Once our client is subscribed any insert/delete/update will streamed to the .NET client. You can test it by adding a some products via the web application and you can see the newly added product get displayed in the console.
How to call a Meteor Method?
class Program { static void Main(string[] args) { IDataSubscriber subscriber = new Subscriber(); DDPClient client = new DDPClient(subscriber); client.Connect("localhost:3000"); client.Call("addProduct", "NS5", "IRobot"); Console.ReadLine(); } }
public class Subscriber:IDataSubscriber { public void DataReceived(dynamic data) { try { if (data.type == "method") Console.WriteLine(data.result); } catch(Exception ex) { throw; } } }
As you can see the Meteor method ‘addProduct’ take two arguments prodCode and prodDesc. So when we call the method we have to pass the parameter as well. We can do that by invoking the ‘Call’ function with the method name and arguments as shown below.
client.Call(“addProduct”, “NS5”, “IRobot”);
Also you will get notification if any data get deleted from the database. You can check the same as shown below.
else if (data.type == "unset") { Console.WriteLine("deleleted item with id: " + data.id);
}
so you will get the id of the data it deleted, you can search for the product with this id and remove or do what ever you wanted to do.
DDPClient.NET is checked into Github. The meteor code I referred here is added to the one I used in Getting Started with meteor.
Getting started with Meteor
This post is an introduction to Meteor and intended to developers who are new to Meteor.
So what is Meteor?
Meteor is an ultra-simple environment for building modern websites. What once took weeks, even with the best tools, now takes hours with Meteor.
Yes Meteor is a java script web framework that can do wonders with less line of code. Watch this Screen cast before you proceed. One of the feature that I really liked is the real time pushing of changed data set to all the connected clients in real time, without any complex code from developers.
Installing Meteor
I use Windows as my development environment, so we need to use the Meteor msi installer. We can get the latest installer from http://win.meteor.com/. Download the setup and install it. After installation we need to start CMD / Bash as administrator or reboot for it to catch the environment changes.
Developing Meteor App
Open the command prompt and change directory to your desired folder, say f:\sony\tracers\meteor. Then issue the create command as shown below.
>meteor create helloworld
Here ‘helloworld’ is my application name. You can give any name for your application. The command creates a folder with the application name with a .meteor folder and sample html and js file. To check whether the application created correctly, type ‘meteor’ in the command prompt as shown below.
As you can see our application is running in localhost, we can fire any browser to that url and can see your first meteor app running. I am leaving the screen shot, see it your self.
Explore Meteor in Detail
It’s time to see some of the cool features of Meteor. I created a small application called pointofsale. Rest of the post will be around this application. It’s a small application I started in Meteor with below functionality.
-
Product Entry
-
Order entry
I completed only Product Entry and Listing.
Disclaimer: I am very bad in Web UI development, so you will see a very ugly UI
Folder Structure
You can find more details about file structuring here. My app’s folder structure is shown below
I use meteor Knockout as my MVVM framework.
Templates
Templates are like User controls in ASP.NET. That has set of controls and logic. Meteor has a nice documentation about Templates, check it out before you move on.
Let’s see the Product Entry Template to get some insight.
<template name="productEntry"> <table> <tr> <td><Label >Product Code</Label></td> <td><label>Product Name</label></td> </tr> <tr> <td><input type="text" id="prodCode" data-bind="value: productCode" placeholder="Code"/></td> <td><input type="text" id="prodName" data-bind="value: productName" placeholder="Name"/></td> <td><input type="button" value="Add" id="addProduct"/></td> </tr> </table> <br> </template>
As I said I use knockout js, so for data binding I added knock out attribute data-bind=”value: productCode” to input text.
Let’s see the java script of Product Entry.
if(Meteor.is_client) { var productCode= ko.observable(); var productName= ko.observable(); var viewModel={ productCode:productCode, productName:productName }; Meteor.startup( function() {ko.applyBindings(viewModel); }); Template.productEntry.events={ "click #addProduct": function(){ var id=Products.insert({prodCode:this.productCode(), prodName:this.productName()}); } }; }
Meteor.is_client will return true if the code is running in client, based on this condition we can add client specific codes. As you can see, some of the code above are knockout specific and am not going in detail, except the event handling. You can learn knockout from http://learn.knockoutjs.com/.
Template.productEntry.events={ "click #addProduct": function(){ var id=Products.insert({prodCode:this.productCode(), prodName:this.productName()}); } };
The above code means, capture all the events in productEntry template. Right now productEntry template has only one button named addProduct and we need to handle the click event. That’s what we are doing in the above code. Leave the Products.Insert now, will come back to that later. So how do we handle a click event of another button, it’s very simple as shown below, just separate two functions with a comma.
Template.productEntry.events={ "click #addProduct": function(){ var id=Products.insert({prodCode:this.productCode(), prodName:this.productName()}); }, "click #showAlert": function(){ alert ("Hellow world"); } };
Meteor Collection
In the above code we are referring an object called Products, what is it? It’s a Meteor collection, meteor uses collection to handle data storage and manipulations. Where is it declared? as this Products collection may require in Server side as well. So I created a file in the root called dbRef.js and declared the collection there as shown below.
Products = new Meteor.Collection("product");
We can use this Products collection to add, remove or search products to display in the client. Have a look at the product listing template to see how to use Products collection to display as list.
<template name="productListing"> <label>Product Listing</label> {{#each products}} {{>product}} {{/each}} </template> <template name="product"> <div class="product {{selected}}"> <span class="code">{{prodCode}}</span> <span class="name">{{prodName}}</span> <span><input type="button" value="Delete" id="delete"></input> </span> </div> </template>
Below is the js file of the template.
if(Meteor.is_client) { Template.productListing.products=function (){ return Products.find(); }; Template.product.events ={ 'click': function(){ Session.set("selected_product", this._id); }, "click #delete": function(){ Products.remove({_id:Session.get("selected_product")}); } }; Template.product.selected = function () { return Session.equals("selected_product", this._id) ? "selected" : ''; }; }
The highlighted ‘products’ function uses the Products collection to return all the products entered. Rest of the code is for deleting and selecting the item in the list.
I think I covered the basics of Meteor, will cover more in coming days. You all can download the source code of pointOfSale from Google Drive