Issue with Push Notification
Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce 2010
Forum Discription: For .NET 4.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=1997
Printed Date: 30-Apr-2025 at 4:17pm
Topic: Issue with Push Notification
Posted By: *Calsy
Subject: Issue with Push Notification
Date 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
|
Replies:
Posted By: kimj
Date 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.
|
Posted By: *Calsy
Date 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?
|
Posted By: kimj
Date 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)
|
Posted By: *Calsy
Date 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
|
Posted By: kimj
Date 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.
|
Posted By: *Calsy
Date 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
|
Posted By: kimj
Date 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.
|
Posted By: pompomJuice
Date 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?
|
Posted By: kimj
Date 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.
|
Posted By: pompomJuice
Date 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.
|
|