HotTowel (Durandal really) and SignalR initialisation - signalr

So I'm integrating SignalR and HotTowel, although really I think this is a matter of how to integrate with Durandal itself.
The issue is I have obviously multiple views. Some of these views I want to respond to SignalR messages. The question is how to do this integration considering that SignalR events have to be started before I call SignalR's hub start method.
So take the example I have view1 and view2. I want each to do something when a SignalR message is received and in the context of that view (so let's say update the DOM somehow). It's an SPA obviously so calling the SignalR start method for each view seems like a bad idea, so starting SignalR once at boot sounds like the right plan, but at that point my views may not have been loaded, and still how would I ensure that my events have the right context for the page.
This is based on my understanding that all events for SignalR have to be registered before I call start. Any thoughts clever people of StackOverflow?
Edit to expand on the problem
Part of the website involves uploading files for parsing and processing to import into a database. I have created a view where the file is selected and uploaded (using FineUploader) to a WebApiController. The controller does the basic steps of checking the uploaded file and then starts an async task to actually do the parsing and processing, while immediately returning the basic "Yep that uploaded fine" message.
This causes the list of 'in progress' files to refresh and the file appears with an 'Uploaded' status. As the async task occurs, the file is parsed, then processed against a rules system, and then finally imported into another back end data store. As each of these status changes occur, SignalR sends messages to the client to notify them of these changes, and thus update the status against the filename. In order for this to occur I must attach a function to the event as it received in SignalR. That even needs some kind of reference to my view (actually viewmodel) so it can update the correct value.
As SignalR should be started once with a call to hub.Start(), I am trying to do it during the 'boot' phase. However when my SPA starts, that view has not been loaded, and therefore neither has that viewmodel, and therefore my function that is responsible for initialising SignalR can have no understanding of the view/viewmodel it must update.
Examples I've seen on using SignalR show it being used in one view, but that doesn't really work surely if you need it in multiple views (you can't just keep calling hub.start() can you)?
Sorry, if this still doesn't make sense I'll post some code or something.

If you use
$.connection.myHub.on("myMethod", function (/* ... */) { /* ... */ });
instead of
$.connection.myHub.client.myMethod = function (/* ... */) { /* ... */ };
you can add client-side hub methods after calling $.connection.hub.start();

Related

Azure Mobile Apps Net Server run a method before Controller Action

I am using the azure-mobile-apps-net-server SDK for my smartphone app backend. Now I want to show the smartphone user some message, when there is a new update available. My idea is to include the current version number of the smartphone app in the header of the request, which goes to the backend.
Now I can read the version in the backend, compare it to some value and throw an HttpResponseException, which the client will catch. Then I can show the client user some message to update to a newer version.
Here some pseudocode:
public void ValidateClientVersion()
{
var version = request.header["X-Client-Version"];
if (version != 3.2.1)
throw new HttpResponseException(...);
}
Now my problem I have multiple Actions in multiple TableControllers. I think there must be some very simple way to call ValidateClientVersion()
before any of the Actions is called. I don't want to add the method call in every single Create, Update, Delete, ... Action.
However as I am new to ASP.Net? or what ever the azure-mobile-apps-net-server Framework is called, I don't know this simple solution.
Can someone point me in the right direction?
It's probably a bad idea to do this over every single version. Your better bet from a user experience perspective is to create a simple WebAPI in your mobile backend that returns the current version, potentially with a download link (based on the OS of the connecting mobile app).
When your mobile app connects, it first calls the WebAPI. If the WebAPI has a different version, then pop up the message and the download link and exit.
This is similar to what we suggest for offline sync schema changes. If the schema version changes, wipe the offline sync SQLite and re-sync.
If you really want do do that you can create a subclass of ApiController, lets call it MyController and make your controllers all derive from it.
Then override the ExecuteAsync function in MyController, put your logic there and end the function with return await base.ExecuteAsync(controllerContext, cancellationToken); so it continues to execute the code in your controller.

What is the correct way to add an EventListener to an AtmosphereResource?

I am using Atmosphere Framework 2.0.8.
I have implemented an AtmosphereHandler in my application and have two way communication occurring correctly over WebSockets and Long Polling.
I am trying to add some handling code for when the client disconnects to clean up some resources specific to that client (ie. I have an entry in a table I want to remove).
I have read the following wiki entries:
OnDisconnect Tricks: https://github.com/Atmosphere/atmosphere/wiki/onDisconnect-tricks
Configuring Atmosphere Listener: https://github.com/Atmosphere/atmosphere/wiki/Configuring-Atmosphere-Listener
The thing I am not clear on is where I should add the call to
atmosphereResource.addEventListener( new AtmosphereResourceEventListenerAdapter() {} );
I eventually found some example code in the JavaDoc for the AtmosphereHandler that registers the EventListener in the onRequest() method. http://atmosphere.github.io/atmosphere/apidocs/org/atmosphere/cpr/AtmosphereHandler.html
What I would like to know is if this is the correct way to go about it?
It is my understanding that the AtmosphereResource represents the connection between a client and the server for the life of that connection. The uuid stays consistent for the object on multiple calls through the onRequest() method from the same client. As such, the same AtmosphereResource object will get the EventListener added every time the onRequest method is called.
This seems wrong. Wouldn't this lead to thousands of EventListeners being registered for each AtmosphereResource?
It seems that the EventLister should only be registered once for each AtmosphereResource.
I feel like I am missing something fundamental here. Could someone please explain?
Here's an example using MeteorServlet, so it won't look exactly like what you'll have to do, but it should get you started. I add the listener to a Meteor instance, and you'll add yours to an AtmosphereResource. Each resource gets just one listener.
The overridden onDisconnect() method calls this Grails service method that handles the event. Of course, you'll want to call something that cleans up your database resource.
Note that the servlet is configured using these options. I think you might need the org.atmosphere.interceptor.HeartbeatInterceptor, but it's been so long since I initially set it up, I can't remember if it's necessary.

What is the best way to implement a inter-qwebview communication?

Overview:
I am trying to create a PoC application that mimics WebIntents-like feature.
So, in my Qt application, I create two QWebviews launching two different webApps. Now let's call them apps A and B.
Scenario:
Main Application creates two QWebViews each launching an App i.e. AppA, AppB.
App A is programmed to fetch some data via AJAX, automatically.
App B also needs part of that data. AppB simply displays a button (HTML) called .
Note: Since, AppA already has that info, I would like the AppB to invoke a JavaScript API which was injected into it's(appB) DOM by means of addToJavaScriptWindowObject() method call when the QWebView was launched.
App-A completed the Ajax Call and indicates the completion in its WebView.
User clicks the button in AppB,
App B invokes that JavaScript API i.e. fetcData({source: "AppA");
Now the control is in the QT-world:
Question: the Control is in the context of AppB, How should I communicate with the WebView in AppA -- i.e. AppB asks AppA: hey AppA, please give me that data that you have fetched?
Can Signals and Slots help me here? Or should I use some other form of IPC.
I read this page: http://qt-project.org/doc/qt-4.8/qtwebkit-bridge.html, but I still didn't get a hint for a solution for my problem.
Another related question: Are QWebViews created in their own threads ?
Can't you just emit some sort of signal from AppB that basically says, "Hey, I finished fetching my data if anyone wants it" or am I missing something? It would happen at the end of AppB::fetchData().
All you have to do after that is connect any interested objects to that signal.

Calling method Asyncronously from aspx

i am using .net4.0 framework
i am working on Web Project using c#
i want to make some request which will populate some items in cache beforehand.
Ex.
user comes to the home page of application.
[ i will write some code in Home Page(.ASPX) which will call some method which will read some files from disk and put them into cache though i don't need this cache on home page... at this point as reading files from disk is going to be somewhat lengthy operation... i would to load home page completely without waiting for response from method(which is going to read files from disk)]
Something like
function page_load{
CacheGenerator.CreateCache();//this is going to be heavy operation..i don't want to wait for this operation to complete
repose.write("Hello world:); // this statement should run moment after above function is called
}
and one more thing can we do this without using threading.
Anything asynchronous is "using threading" in one way or another.
More importantly, you should not start any async operation from a page. The page only exists in memory for the duration of the request. Your async operation may complete after the page no longer exists in memory.
You may be able to use the Task class to start an async operation from the Application_Start event in global.asax.

Custom Windows Workflow activity that executes an asynchronous operation - redone using generic service

I am writing a custom Windows Workflow Foundation activity, that starts some process asynchronously, and then should wake up when an async event arrives.
All the samples I’ve found (e.g. this one by Kirk Evans) involve a custom workflow service, that does most of the work, and then posts an event to the activity-created queue. The main reason for that seems to be that the only method to post an event [that works from a non-WF thread] is WorkflowInstance.EnqueueItem, and the activities don’t have access to workflow instances, so they can't post events (from non-WF thread where I receive the result of async operation).
I don't like this design, as this splits functionality into two pieces, and requires adding a service to a host when a new activity type is added. Ugly.
So I wrote the following generic service that I call from the activity’s async event handler, and that can reused by various async activities (error handling omitted):
class WorkflowEnqueuerService : WorkflowRuntimeService
{
public void EnqueueItem(Guid workflowInstanceId, IComparable queueId, object item)
{
this.Runtime.GetWorkflow(workflowInstanceId).EnqueueItem(queueId, item, null, null);
}
}
Now in the activity code, I can obtain and store a reference to this service, start my async operation, an when it completes, use this service to post an event to my queue. The benefits of this - I keep all the activity-specific code inside activity, and I don't have to add new services for each activity types.
But seeing the official and internet samples doing it will specialized non-reusable services, I would like to check if this approach is OK, or I’m creating some problems here?
There is a potential problem here with regard to workflow persistence.
If you create long running worklfows that are persisted in a database to the runtime will be able to restart these workflows are not reloaded into memory until there is some external event that reloads them. As there they are responsible for triggering the event themselves but cannot until they are reloaded. And we have a catch 22 :-(
The proper way to do this is using an external service. And while this might feel like dividing the code into two places it really isn't. The reason is that the workflow is responsible for the big picture, IE what should be done. And the runtime service is responsible for the actual implementation or how it should be done. That way you can change the how without changing the why and when part.
A followup - regardless of all the reasons, why it "should be done" using a service, this will be directly supported by .NET 4.0, which provides a clean way for an activity to start an asynchronous work, while suspending the persistence of the activity.
See
http://msdn.microsoft.com/en-us/library/system.activities.codeactivitycontext.setupasyncoperationblock(VS.100).aspx
for details.

Resources