New Posts New Posts RSS Feed: Issue with Push Notification
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Issue with Push Notification

 Post Reply Post Reply
Author
*Calsy View Drop Down
Groupie
Groupie


Joined: 02-Feb-2009
Location: Australia
Posts: 69
Post Options Post Options   Quote *Calsy Quote  Post ReplyReply Direct Link To This Post Topic: Issue with Push Notification
    Posted: 22-Jul-2010 at 5:18pm
Hi All, Im trying to create a simple push notification so that when a record is entered into the database the client is notified.
 
The problem is when i call the "__notificationManager.Send" from the server my client doesnt seem to pick it up (i.e. the method i set as the callback in my registercallback is not being entered). Following is my code:
 
Client side:
 
****************************

Private _owToken As String

Private Sub SetupListenerTest()

_owToken = "2"

TestEntities.DefaultManager.RegisterCallback("DomainModel.ChatListener, DomainModel", "NewChatMessage", AddressOf ChatCallBack, _owToken, SystemProperties.CurrentLoggedInUser.TestUserID)

End Sub

Private Sub ChatCallBack(ByVal op As SubscriptionOperation)

MessageBox.Show("CALL BACK HIT")

End Sub

****************************
 
Server Side:
 
****************************

Imports System

Imports System.Linq

Imports System.Threading

Imports IdeaBlade.EntityModel

Imports IdeaBlade.Core

Public Class ChatListener

Private Shared __serviceKey As Guid

Private Shared __notificationManager As INotificationManager

Private Shared __entityManager As TestEntities

Private Shared __lastCheckTime As DateTime = DateTime.SpecifyKind(DateTime.Today, DateTimeKind.Utc)

<AllowRpc()> _

Public Shared Sub NewChatMessage(ByVal serviceKey As Guid, ByVal notificationManager As INotificationManager, ByVal entityManager As EntityManager)

__serviceKey = serviceKey

__notificationManager = notificationManager

__entityManager = New TestEntities(entityManager)

' Create a sub-typed server-side EM.

TraceFns.WriteLine("Chat Listener started")

While True

'LOOP THROUGH AND SEND ALL THE TIME (FOR TESTING)

CheckForNewChat()

End While

TraceFns.WriteLine("Chat exiting")

End Sub

Private Shared Sub CheckForNewChat()

'CALL IT EVERYTIME REGARDLESS

For Each subscriber As Object In __notificationManager.GetSubscribers(__serviceKey)

__notificationManager.Send(__serviceKey, subscriber, "SEND TO CALL BACK")

Next

End Sub

End Class

****************************
 
It executes the NewChatMessage and CheckForNewChat message correctly, but nothing happens when i call the "__notificationManager.Send(__serviceKey, subscriber, "SEND TO CALL BACK") line.
 
Ive checked all references against the ideablade sample, ive double checked the web.config and made sure it is a spinning image of the ideablade sample web.config.
 
Any ideas on why the Callback wouldnt be being raised???
 
Thanks in advance
 
Back to Top
kimj View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 1391
Post Options Post Options   Quote kimj Quote  Post ReplyReply Direct Link To This Post Posted: 22-Jul-2010 at 6:26pm

Are you doing this in a Silverlight application?  If so, be sure to include the following:

In the Silverlight application - add references to IdeaBlade.EntityModel.Push.SL.dll and System.ServiceModel.PollingDuplex.dll.  You can find the polling duplex dll in the Silverlight SDK "Libraries\Client" folder.
 
In the web application - add a reference to the System.ServiceModel.PollingDuplex.dll, which you can also find in the Silverlight SDK but in the "Libraries\Server" folder.
 
Also check the debug log in the web project to see if any pertinent messages were written there. 
 
 
 
Back to Top
*Calsy View Drop Down
Groupie
Groupie


Joined: 02-Feb-2009
Location: Australia
Posts: 69
Post Options Post Options   Quote *Calsy Quote  Post ReplyReply Direct Link To This Post Posted: 22-Jul-2010 at 6:45pm

Hi Kim, I already checked the references.

I checked the log and it is throwing the following message:
 
Removing subscriber after error Type 'IdeaBlade.EntityModel.NotificationSubscriber' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.
 
Any ideas?
Back to Top
kimj View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 1391
Post Options Post Options   Quote kimj Quote  Post ReplyReply Direct Link To This Post Posted: 22-Jul-2010 at 7:15pm
Does the sample for the "OrderWatcher" service actually work for you?  I'm thinking this might be an issue with VB and the overloads defined on the NotificationManager Send method, which are:

void Send(Guid serviceKey, params Object[] args);
void Send(Guid serviceKey, NotificationSubscriber subscriber, params Object[] args);

Since the NotificationSubscriber is being serialized with the message then it does look like the wrong overload is being chosen by the compiler.
 
For the moment, since your sample code is not sending subscriber-specific messages, try instead doing a "broadcast" type of send to all subscribers, as shown in the "LongRunningProcedure" service.
 
ETA - I just saw that you're typing subscriber as an object in your foreach loop.  Instead use:
For Each subscriber As NotificationSubscriber In __notificationManager.GetSubscribers(__serviceKey)


Edited by kimj - 22-Jul-2010 at 7:19pm
Back to Top
*Calsy View Drop Down
Groupie
Groupie


Joined: 02-Feb-2009
Location: Australia
Posts: 69
Post Options Post Options   Quote *Calsy Quote  Post ReplyReply Direct Link To This Post Posted: 22-Jul-2010 at 7:24pm

Yeah I changed the line:

 __notificationManager.Send(__serviceKey, subscriber, "SEND TO CALL BACK")
 
to:
 
__notificationManager.Send(__serviceKey,  "SEND TO CALL BACK")
 
And it worked.
 
It does look like it is a vb issue (the csharp Push sample worked perfectly), same as what i had with the savechanges overloads with the version before last.
 
Problem is i cant be doing a broadcast for this situation because it will kill performance. Is there a workaround or a fix for this?
 
Thanks
Back to Top
kimj View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 1391
Post Options Post Options   Quote kimj Quote  Post ReplyReply Direct Link To This Post Posted: 23-Jul-2010 at 10:02am
Yes, the workaround is to do what I mentioned when I edited my last post, your loop would look like this -
 
For Each subscriber As NotificationSubscriber  In __notificationManager.GetSubscribers(__serviceKey)
__notificationManager.Send(__serviceKey, subscriber, "SEND TO CALL BACK")
Next
 
In those situations where you are sending exactly the same message to all subscribers, then not looping through the GetSubscribers list but instead calling Send(serviceKey, message[s]) is the way to go.


Edited by kimj - 23-Jul-2010 at 10:03am
Back to Top
*Calsy View Drop Down
Groupie
Groupie


Joined: 02-Feb-2009
Location: Australia
Posts: 69
Post Options Post Options   Quote *Calsy Quote  Post ReplyReply Direct Link To This Post Posted: 25-Jul-2010 at 3:40pm
Hi Kim, Sorry missed that part of the post (blonde moment).
 
Changing the type to NotificationSubscriber has fixed the issue.
 
Thanks for your help.
 
One question. If a user subscribes and than they just close the browser and we dont CancelCallBack on their subscripton. Will their subscription just be left there in the notificationManager's Subscription pool? Is there anything we can do about this if this is the case?
 
Thanks
Back to Top
kimj View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 1391
Post Options Post Options   Quote kimj Quote  Post ReplyReply Direct Link To This Post Posted: 26-Jul-2010 at 10:33am
The NotificationManager does periodic cleanup (this is currently performed every 10 minutes and is not configurable) on the subscription pool.  When any attempt to send a message to or ping the subsriber fails the subscriber is removed from the pool.
 
Back to Top
pompomJuice View Drop Down
Newbie
Newbie
Avatar

Joined: 29-Jul-2010
Location: ZA
Posts: 28
Post Options Post Options   Quote pompomJuice Quote  Post ReplyReply Direct Link To This Post Posted: 13-Aug-2010 at 2:08am

Could you do something like the following in your push service handler on the server?

 
 

__entityManager.EntityChanged += (s, e) =>

__notificationManager.GetSubscribers(__serviceKey).ForEach(subscriber =>

__notificationManager.Send(__serviceKey,subscriber,"Entity Changed"));

I am trying to scan for changes on the server side and broadcast them and it's not working.
 
Any ideas?
Back to Top
kimj View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 1391
Post Options Post Options   Quote kimj Quote  Post ReplyReply Direct Link To This Post Posted: 13-Aug-2010 at 8:38am
The EntityManager provided to the Push service method is one of the special server-side only EMs created by DevForce for server-side code, as such, there won't be any activity on it other that what you do in that specific method, so listening for EntityChanged, or any other event, won't accomplish what you need. 
 
We don't have any recommendations on how to "listen" for server-side changes.   One possibility, out of many, might be to implement a custom EntityServerSaveInterceptor and send messages regarding changes to the Push service method.
Back to Top
pompomJuice View Drop Down
Newbie
Newbie
Avatar

Joined: 29-Jul-2010
Location: ZA
Posts: 28
Post Options Post Options   Quote pompomJuice Quote  Post ReplyReply Direct Link To This Post Posted: 16-Aug-2010 at 6:20am
Originally posted by kimj

The EntityManager provided to the Push service method is one of the special server-side only EMs created by DevForce for server-side code, as such, there won't be any activity on it other that what you do in that specific method, so listening for EntityChanged, or any other event, won't accomplish what you need. 
 
We don't have any recommendations on how to "listen" for server-side changes.   One possibility, out of many, might be to implement a custom EntityServerSaveInterceptor and send messages regarding changes to the Push service method.

That is good to know.

I have created a custom EntityServerSaveInterceptor (as you suggested) and managed to send that information to my push notifier and it is working brilliantly. Now if a user makes a change to a entity in one browser, another browser could get this information and act on it in real time. It is completely event driven, zero polling! (In silverlight 4)

The only issues I have now is that the current push notification service is to much of a "black box" service. For example, I implemented a push service that spams notifications to subscribers, only to notice that the notification manager seems to only burst notifications every 6 seconds. It would have been nice to have a piece of documentation that describes these kinds of behaviors. 


Edited by pompomJuice - 16-Aug-2010 at 6:25am
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down