RavenDB Alternative to Polling (push notifications) - ravendb

I have an app that uses RavenDB. It has a WPF front-end GUI app. I would like for that app to be notified of certain types of new documents. For example, if my app loads the most recent 50 Foos for display, and someone else adds 10 more Foos later, I would like the app to know about these new 10 and update the UI.
I could poll the DB every few seconds to check for new documents, but it would be nice to have a real-time, two-way call-back notification from RavenDB. Does this functionality exist?
My searches have ended with smuggler and listeners, but I don't know that either is intended for this purpose.

RavenDB V2 will support push notifications:
store.Changes()
.ForDocument("users/1")
.Subscribe(notification => {
using(var session = store.OpenSession())
{
var user = session.Load<User>(notification.Name);
Console.WriteLine("Wow! " + notification.Name + " changed. New name: " + user.Name);
}
});

Related

display leaderboard using google play services

I am trying to display a leaderboard for my game using google play services. The game is html/js. I have an instance of gapi loaded. I submit a score in the following way:
var json={};
json.leaderboardId='dlsfhqo3irhq';
json.score=666;
gapi.client.games.scores.submit(json);
I then try to display a leaderboard as follows:
var json={};
json.leaderboardId='dlsfhqo3irhq';
json.collection='PUBLIC';
json.timeSpan='ALL_TIME';
gapi.client.games.scores.listWindow(json);
Nothing appears. I have set up the leaderboard in the developer console which says it is ready for testing. Also I am displaying the leaderboard in response to a click so that no popups are blocked.
All of the google (game) api's have two stages. First is to setup the request, then you need to execute.
Your code should look something like:
var json= { leaderboardId: 'dlsfhqo3irhq', collection: 'PUBLIC', timeSpan:'ALL_TIME'};
var request = gapi.client.games.scores.listWindow(json);
request.execute(function(response) {
// do something
});

Worklight initialization for Android always clears WebView history

I noticed cordovaInitCallback is called each time Worklight/Cordova is initialized in an Android app. In particular, it calls Cordova's "clearHistory" to wipe out the WebView history. This has been an issue when I try to make use of window.history in a multi-page app since the history is always reset during the initializtion from page to page.
Since the comment suggests that the purpose for this clearHistory call is to prevent going back to an old page in a direct update scenario, could the condition be strengthened over an Android environment check so that it is only called if a direct update has just taken place? One case, for example, I can think of is when connectOnStartup=false, then direct update would not occur.
wlclient.js:
var cordovaInitCallback = function(returnedData) {
onEnvInit(options);
if (WL.Client.getEnvironment() == WL.Env.ANDROID) {
if (returnedData !== null && returnedData !== "") {
WL.StaticAppProps.APP_VERSION = returnedData;
}
// In development mode, the application has a settings
// widget in which the user may alter
// the application's root url
// and here the application reads this url, and replaces the
// static prop
// WL.StaticAppProps.WORKLIGHT_ROOT_URL
// __setWLServerAddress for iOS is called within
// wlgap.ios.js's wlCheckReachability
// function because it is an asynchronous call.
// Only in Android we should clear the history of the
// WebView, otherwise when user will
// press the back button after upgrade he will return to the
// html page before the upgrade
if (**WL.Env.ANDROID == getEnv()**) {
cordova.exec(null, null, 'Utils', 'clearHistory', []);
}
}
I am currently using Worklight 5.0.5, and have checked this same condition exists in 5.0.5.1.
Thanks!
The architectural design of Worklight is SPA (Single Page Application).
cordovaInitCallback should be called only once in the life cycle of the application.
That said, you can, if you wish, override it.

Update live tile at fixed interval without having the app running

How can I update my app's live tile at a fixed interval, for example half a day, using JavaScript?
Moreover, it has to be able to update even though the app itself is not running (like the weather app for example)
EDIT: I want to update it locally without having to connect to the internet. And please give some example in JavaScript, not C# please!
To be more specific, for example, how can I set the tile to update once per day, showing the current date?
If the content on the tile is going to be the date, scheduled tile updates are a good option (see ScheduledTileNotification and the JavaScript Scheduled notifications sample on MSDN). You can schedule a notification to occur once a day with the date as the content.
If you can stand up a web service, periodic updates would be a good option. Using this approach, a tile will be updated on a fixed interval whether or not the app is running. Alternatively, you could use push, or update the tile using a background task.
MSDN has a good article on choosing the right notification delivery mechanism, and links to related code samples: http://msdn.microsoft.com/en-us/library/windows/apps/hh779721.aspx
You can use a background task on a schedule for an interval for anything greater than 15 mins. The tasks are designed to be run by the OS separate to your application, so will be executed if it is not active or open.
Here is a detailed blog post on getting started with background tasks: http://www.silverlightshow.net/items/Windows-8-metro-make-your-app-alive-with-background-tasks.aspx
Register a Background Task that executes ever 12 hours and Updates your Tile.
var RegisterBackgroundTask = function (taskEntryPoint, taskName, trigger, condition) {
UnregisterTask(taskName);
Windows.ApplicationModel.Background.BackgroundExecutionManager.requestAccessAsync();
var TaskBuilder = new Windows.ApplicationModel.Background.BackgroundTaskBuilder();
TaskBuilder.name = taskName;
TaskBuilder.taskEntryPoint = taskEntryPoint;
TaskBuilder.setTrigger(trigger);
if (condition !== null) {
TaskBuilder.addCondition(condition);
// If the condition changes while the background task is executing then it will be canceled.
TaskBuilder.cancelOnConditionLoss = true;
}
var task = TaskBuilder.register();
// Remove previous completion status from local settings.
var settings = Windows.Storage.ApplicationData.current.localSettings;
settings.values.remove(taskName);
};
var UnregisterBackgroundTask = function (sTaskName) {
var iter = Windows.ApplicationModel.Background.BackgroundTaskRegistration.allTasks.first();
var hascur = iter.hasCurrent;
while (hascur) {
var cur = iter.current.value;
if (cur.name === sTaskName) {
cur.unregister(true);
}
hascur = iter.moveNext();
}
}
Register Task like this:
RegisterTask(
"App_JS\\LiveTileTask.js",
"Task.LiveTileTask",
new Windows.ApplicationModel.Background.TimeTrigger(15, false),
new Windows.ApplicationModel.Background.SystemCondition(Windows.ApplicationModel.Background.SystemConditionType.internetAvailable)); // 15 min are minimum
In a dedicated File "LiveTileTask.js" you write the Code of your Live Tile Updater:
(function () {
"use strict";
importScripts("//Microsoft.Phone.WinJS.2.1/js/base.js");
var backgroundTaskInstance = Windows.UI.WebUI.WebUIBackgroundTaskInstance.current;
var Notifications = Windows.UI.Notifications;
var tileUpdateManager = Notifications.TileUpdateManager.createTileUpdaterForApplication();
tileUpdateManager.clear();
tileUpdateManager.enableNotificationQueue(true);
for (var i = 0; i < 6; i++) {
var tileWideXml = Notifications.TileUpdateManager.getTemplateContent(Notifications.TileTemplateType.tileSquare150x150Text04),
tileAttributes = tileWideXml.getElementsByTagName("text");
tileAttributes[0].appendChild(tileWideXml.createTextNode("My Live Tile Text No. " + i));
var currentTime = new Date(),
dueTime = new Date(currentTime.getTime() + 30),
tileNotification = new Notifications.ScheduledTileNotification(xmlTile, dueTime),
tileUpdater = Notifications.TileUpdateManager.createTileUpdaterForApplication();
tileUpdater.addToSchedule(tileNotification);
}
backgroundTaskInstance.succeeded = true;
close();
})();
Finally do not forget to register the backgroundtask in your appxmanifest. Under "declarations" select "Background Task" and activate "Timer" and set "Start Page" to "App_JS\LiveTileTask.js". This way you should be able to update your Tile.
You use Azure and Push Notifications to send out notifications to all your app users: http://msdn.microsoft.com/en-us/library/windows/apps/hh465460.aspx
I recommend you create an Azure Mobile Service. It's really easy and cheap and means you get all of the advantages of a separate push service (instead of a scheduled tile notification on the device) to send your push notifications but without all the work. You can sign up for a free trial if you'd like and create up to 10 mobile services for free. You just create a mobile services and then create a scheduled script that runs every 12 hours and in the script you write a little bit of server-side JavaScript code that does your push. That's just one of the things the Mobile Services gives you. You also get data, authentication, and more. www.windowsazure.com

Determine recently queued/number of queues for titles, recently watched, etc via Netflix API

I've seen other websites (InstantWatcher & Instant Watch DB) doing this, but how? I don't see anything in the API that exposes this kind of data? This is driving me batty! How are they doing it?! Am I missing something in the API??
And there is nothing in Google-land regarding this. I've looked...
You need to start tracking this data on your own. You can put a JavaScript hook on the "play" or "queue" buttons/links that pings you server and increments the queue/play count for the title in your datastore.
If you look at the add queue button on instantwatchdb.com, you'll see this kind of hook:
<a href="#" class="modal"
onclick="javascript:nflx.addToQueue(
'http://api.netflix.com/catalog/titles/movies/60024224',
-230, -15, '8zgw3pprk2n5byjfuv3f52y4', 'instant', 'title_links');
logQueue('166252'); return false; return false;">Add to Instant Queue</a>
The logQueue call is to an custom JavaScript that increments the local queue count.
function logQueue(movieId)
{
new Ajax.Request('/ajax/activity/queue', {
method: 'post',
parameters: {
movie: movieId
}
});
}

How do I get data from a background page to the content script in google chrome extensions

I've been trying to send data from my background page to a content script in my chrome extension. i can't seem to get it to work. I've read a few posts online but they're not really clear and seem quite high level. I've got managed to get the oauth working using the Oauth contacts example on the Chrome samples. The authentication works, i can get the data and display it in an html page by opening a new tab.
I want to send this data to a content script.
i'm having a lot of trouble with this and would really appreciate if someone could outline the explicit steps you need to follow to send data from a bg page to a content script or even better some code. Any takers?
the code for my background page is below (i've excluded the oauth paramaeters and other )
` function onContacts(text, xhr) {
contacts = [];
var data = JSON.parse(text);
var realdata = data.contacts;
for (var i = 0, person; person = realdata.person[i]; i++) {
var contact = {
'name' : person['name'],
'emails' : person['email']
};
contacts.push(contact); //this array "contacts" is read by the
contacts.html page when opened in a new tab
}
chrome.tabs.create({ 'url' : 'contacts.html'}); sending data to new tab
//chrome.tabs.executeScript(null,{file: "contentscript.js"});
may be this may work?
};
function getContacts() {
oauth.authorize(function() {
console.log("on authorize");
setIcon();
var url = "http://mydataurl/";
oauth.sendSignedRequest(url, onContacts);
});
};
chrome.browserAction.onClicked.addListener(getContacts);`
As i'm not quite sure how to get the data into the content script i wont bother posting the multiple versions of my failed content scripts. if I could just get a sample on how to request the "contacts" array from my content script, and how to send the data from the bg page, that would be great!
You have two options getting the data into the content script:
Using Tab API:
http://code.google.com/chrome/extensions/tabs.html#method-executeScript
Using Messaging:
http://code.google.com/chrome/extensions/messaging.html
Using Tab API
I usually use this approach when my extension will just be used once in a while, for example, setting the image as my desktop wallpaper. People don't set a wallpaper every second, or every minute. They usually do it once a week or even day. So I just inject a content script to that page. It is pretty easy to do so, you can either do it by file or code as explained in the documentation:
chrome.tabs.executeScript(tab.id, {file: 'inject_this.js'}, function() {
console.log('Successfully injected script into the page');
});
Using Messaging
If you are constantly need information from your websites, it would be better to use messaging. There are two types of messaging, Long-lived and Single-requests. Your content script (that you define in the manifest) can listen for extension requests:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.method == 'ping')
sendResponse({ data: 'pong' });
else
sendResponse({});
});
And your background page could send a message to that content script through messaging. As shown below, it will get the currently selected tab and send a request to that page.
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendRequest(tab.id, {method: 'ping'}, function(response) {
console.log(response.data);
});
});
Depends on your extension which method to use. I have used both. For an extension that will be used like every second, every time, I use Messaging (Long-Lived). For an extension that will not be used every time, then you don't need the content script in every single page, you can just use the Tab API executeScript because it will just inject a content script whenever you need to.
Hope that helps! Do a search on Stackoverflow, there are many answers to content scripts and background pages.
To follow on Mohamed's point.
If you want to pass data from the background script to the content script at initialisation, you can generate another simple script that contains only JSON and execute it beforehand.
Is that what you are looking for?
Otherwise, you will need to use the message passing interface
In the background page:
// Subscribe to onVisited event, so that injectSite() is called once at every pageload.
chrome.history.onVisited.addListener(injectSite);
function injectSite(data) {
// get custom configuration for this URL in the background page.
var site_conf = getSiteConfiguration(data.url);
if (site_conf)
{
chrome.tabs.executeScript({ code: 'PARAMS = ' + JSON.stringify(site_conf) + ';' });
chrome.tabs.executeScript({ file: 'site_injection.js' });
}
}
In the content script page (site_injection.js)
// read config directly from background
console.log(PARAM.whatever);
I thought I'd update this answer for current and future readers.
According to the Chrome API, chrome.extension.onRequest is "[d]eprecated since Chrome 33. Please use runtime.onMessage."
See this tutorial from the Chrome API for code examples on the messaging API.
Also, there are similar (newer) SO posts, such as this one, which are more relevant for the time being.