Author |
Share Topic Topic Search Topic Options
|
*Calsy
Groupie
Joined: 02-Feb-2009
Location: Australia
Posts: 69
|
Post Options
Quote Reply
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
|
|
kimj
IdeaBlade
Joined: 09-May-2007
Posts: 1391
|
Post Options
Quote Reply
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.
|
|
*Calsy
Groupie
Joined: 02-Feb-2009
Location: Australia
Posts: 69
|
Post Options
Quote Reply
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?
|
|
kimj
IdeaBlade
Joined: 09-May-2007
Posts: 1391
|
Post Options
Quote Reply
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
|
|
*Calsy
Groupie
Joined: 02-Feb-2009
Location: Australia
Posts: 69
|
Post Options
Quote Reply
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
|
|
kimj
IdeaBlade
Joined: 09-May-2007
Posts: 1391
|
Post Options
Quote Reply
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
|
|
*Calsy
Groupie
Joined: 02-Feb-2009
Location: Australia
Posts: 69
|
Post Options
Quote Reply
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
|
|
kimj
IdeaBlade
Joined: 09-May-2007
Posts: 1391
|
Post Options
Quote Reply
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.
|
|
pompomJuice
Newbie
Joined: 29-Jul-2010
Location: ZA
Posts: 28
|
Post Options
Quote Reply
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?
|
|
kimj
IdeaBlade
Joined: 09-May-2007
Posts: 1391
|
Post Options
Quote Reply
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.
|
|
pompomJuice
Newbie
Joined: 29-Jul-2010
Location: ZA
Posts: 28
|
Post Options
Quote Reply
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
|
|