Print Page | Close Window

Push event - new entry in db

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=2334
Printed Date: 29-Jul-2026 at 10:06am


Topic: Push event - new entry in db
Posted By: danjal
Subject: Push event - new entry in db
Date Posted: 24-Nov-2010 at 7:11am

We are using DevForce 2010 v6.0.6.0, MVVM and Prism.

One of our modules is handling alarms, which are entries in one of our database-tables.

 

Is it possible to let the entitymodel push events to our modules if a new entry has arrived in our database-tables.

 

Is there any samplecode/documentation about this?

 




Replies:
Posted By: smi-mark
Date Posted: 24-Nov-2010 at 9:06am
It really depends on your scenario.

If your database is ONLY updated through the BOS, you could have clients subscribe to a notification on the server, and quite easily accomplish this by sending out a notification when an alarm is added.

If you have other software that talks directly to the database, then you would want to look into implementing SQLDependency. Another option is to query the table on a set interval looking for new rows.

See this link for a push notification example:

http://drc.ideablade.com/xwiki/bin/view/Documentation/Documentation_Code_PushNotification


Posted By: danjal
Date Posted: 25-Nov-2010 at 8:49am

Thank you smi-mark!

 

Great example.

 

But I have run into problems.

I have added all references and assemblies, as ordered.

 

My client side code looks something like this:

public void SubscribeAlarmEvents()

{

m_token = new Guid();

p_manager.RegisterCallback(

                "ServerModelC2Net.AlarmWatcher, ServerModelC2Net",

                "NewAlarmService",

                AlarmPushCallback,

                m_token);

}

 

private void AlarmPushCallback(SubscriptionOperation op)

{

MessageBox.Show("New Alarm!!!");

}

 

And my server side something like this:

[AllowRpc]

public static void NewAlarmService(Guid servicekey, INotificationManager notificationManager, EntityManager entityManager)

{

m_serviceKey = servicekey;

m_notificationManager = notificationManager;

m_entityManager = new C2NetDomainModelEntityManager(entityManager);

 

TraceFns.WriteLine("AlarmWatcher started");

 

while (true)

{

CheckForNewAlarms();

//sleep for 60 seconds

Thread.Sleep(1000*60*1);

}

 

TraceFns.WriteLine("AlarmWatcher stopping");

}

 

private static void CheckForNewAlarms()

{

var newAlarms = m_entityManager.EntAlarms.Where(e => e.p_timestamp >= m_lastCheckTime).ToList();

m_lastCheckTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc);

           

if (newAlarms.Count()==0) return;

m_notificationManager.Send(m_serviceKey, newAlarms.Count());

}

 

These are some of the entries in the debuglog:

 

Date

Time

UserName

Namespace

Class:Method

Message

2010-11-25

15:56:59

Xxx

IdeaBlade.EntityModel.Server

NotificationServiceManager::.ctor

NotificationServiceManager started

2010-11-25

15:56:59

Xxx

IdeaBlade.EntityModel.Server

NotificationServiceManager::RegisterUser

New user registered for NewAlarmService

2010-11-25

15:56:59

Xxx

IdeaBlade.EntityModel.Server

NotificationThreadHelper::RunServerMethod

NewAlarmService is starting on thread 27

2010-11-25

15:56:59

Xxx

ServerModelC2Net

AlarmWatcher::NewAlarmService

AlarmWatcher started

2010-11-25

15:56:59

Xxx

IdeaBlade.EntityModel.Server

EntityServerQueryInterceptor::ExecuteQuery

Fetch ... value(IdeaBlade.EntityModel.EntityQueryProxy`1[ServerModelC2Net.EntAlarm]).Where(e => (e.p_timestamp >= 25.11.2010 00:00:00))

2010-11-25

15:57:59

Xxx

IdeaBlade.EntityModel.Server

EntityServerQueryInterceptor::ExecuteQuery

Fetch ... value(IdeaBlade.EntityModel.EntityQueryProxy`1[ServerModelC2Net.EntAlarm]).Where(e => (e.p_timestamp >= 25.11.2010 15:56:59))

2010-11-25

15:58:59

Xxx

IdeaBlade.EntityModel.Server

EntityServerQueryInterceptor::ExecuteQuery

Fetch ... value(IdeaBlade.EntityModel.EntityQueryProxy`1[ServerModelC2Net.EntAlarm]).Where(e => (e.p_timestamp >= 25.11.2010 15:57:59))

2010-11-25

15:59:02

Xxx

IdeaBlade.EntityModel.Server

NotificationServiceManager::AsyncNotify

Removing subscriber after error The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it has been Aborted.

2010-11-25

15:59:02

Xxx

IdeaBlade.EntityModel.Server

NotificationServiceManager::UnregisterUser

User unregistered from NewAlarmService

2010-11-25

15:59:02

Xxx

IdeaBlade.EntityModel.Server

NotificationThreadHelper::StopThread

Stopping thread for NewAlarmService

2010-11-25

15:59:02

Xxx

IdeaBlade.EntityModel.Server

NotificationServiceManager::NotificationThreadCompleted

Server method completed: NewAlarmService

 

 

After I insert a new alarm in the database, I get the “Removing subscriber after error...” in my debuglog.

I also know that

m_notificationManager.Send(m_serviceKey, newAlarms.Count());

is executed.

 

What is wrong?

 



Posted By: smi-mark
Date Posted: 25-Nov-2010 at 8:35pm
Hmm lets see your config file..

Have you tried coding it like the example, by calling GetSubscribers?



Posted By: danjal
Date Posted: 26-Nov-2010 at 3:46am

Yes I have also tried with GetSubscribers – same behavior and error.

I should note that the push notification example from Ideablade runs fine.

 

Here is my webconfig:

<?xml version="1.0"?>

<configuration>

       <configSections>

             <section name="ideablade.configuration" type="IdeaBlade.Core.Configuration.IdeaBladeSection, IdeaBlade.Core"/>

       </configSections>

       <ideablade.configuration version="6.00" xmlns="http://schemas.ideablade.com/2010/IdeaBladeConfig">

             <objectServer>

                    <serverSettings loginManagerRequired="true"/>

             </objectServer>

    <!-- Enable the Push service -->

    <notificationService enabled="true" />

             <!--    <probeAssemblyNames>

       <probeAssemblyName name="C2Net.CommonClasses"/>

       <probeAssemblyName name="C2NetServer"/>

       <probeAssemblyName name="ServerModelC2Net"/>

     </probeAssemblyNames> -->

             <logging logFile="log\DebugLog.xml"/>

       </ideablade.configuration>

       <system.serviceModel>

             <!-- Set this to true to allow use of ASP.NET security features. -->

             <serviceHostingEnvironment aspNetCompatibilityEnabled="false"/>

       </system.serviceModel>

       <system.web>

             <compilation debug="true" targetFramework="4.0">

                    <assemblies>

                           <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

                    </assemblies>

             </compilation>

             <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>

       </system.web>

       <!--  The system.webServer section is required when hosting a Silverlight application under Internet

        Information Services 7.0.  It is not necessary for previous version of IIS.

    -->

       <connectionStrings>

             <add name="..." connectionString="...;" providerName="System.Data.EntityClient"/>

       </connectionStrings>

</configuration>

 

 

I have changed my service a little bit, to simplify things. Now it sends an event periodically:

[AllowRpc]

public static void NewAlarmService(Guid servicekey, INotificationManager notificationManager, EntityManager entityManager)

{

m_serviceKey = servicekey;

m_notificationManager = notificationManager;

m_entityManager = new C2NetDomainModelEntityManager(entityManager);

 

TraceFns.WriteLine("AlarmWatcher started");

 

while (true)

{

TraceFns.WriteLine("Sending alarm event");

m_notificationManager.Send(m_serviceKey, new AlarmCount(1));

TraceFns.WriteLine("Alarm event sent");

 

//sleep for 60 seconds

Thread.Sleep(1000*60*1);

}

TraceFns.WriteLine("AlarmWatcher stopping");

}

 

When I run this, I get the first event, but not the rest of the events.

Here is my debugLog - maybe the last entry provides a clue?

 

 

Date

Time

UserName

Namespace

Class:Method

Message

2010-11-26

11:18:30

IdeaBlade.EntityModel

KnownTypeHelper::<GetMarkedKnownTypes>b__13

Probed for known types and found ServerModelC2Net.AlarmCount

2010-11-26

11:18:30

IdeaBlade.EntityModel

RemoteServiceFns::AddSerializationBehavior

Using DC serializer for EntityServer

2010-11-26

11:18:30

IdeaBlade.EntityModel

RemoteServiceFns::AddSerializationBehavior

Using DC serializer for NotificationService

2010-11-26

11:18:30

IdeaBlade.EntityModel.Server

EntityServerHostFactory::CreateServiceHost

EntityServer listening on http://localhost:9009/EntityServer.svc/sl

2010-11-26

11:18:30

IdeaBlade.EntityModel.Server

EntityServerHostFactory::CreateServiceHost

EntityServer listening on http://localhost:9009/EntityServer.svc/sl-NotificationService

2010-11-26

11:18:32

C2NetServer

LoginManager::EnterLogin

LoginManager: Entered

2010-11-26

11:18:32

C2NetServer

LoginManager::GetUser

LoginManager: asking db for the user.

2010-11-26

11:18:33

C2NetServer

LoginManager::GetUser

LoginManager: got user from the db.

2010-11-26

11:18:33

C2NetServer

LoginManager::ExitingSuccessfully

LoginManager: returning without exception.

2010-11-26

11:18:37

Xxx

IdeaBlade.EntityModel.Server

NotificationServiceManager::.ctor

NotificationServiceManager started

2010-11-26

11:18:37

Xxx

IdeaBlade.EntityModel.Server

NotificationServiceManager::RegisterUser

New user registered for NewAlarmService

2010-11-26

11:18:37

Xxx

IdeaBlade.EntityModel.Server

NotificationThreadHelper::RunServerMethod

NewAlarmService is starting on thread 18

2010-11-26

11:18:37

Xxx

ServerModelC2Net

AlarmWatcher::NewAlarmService

AlarmWatcher started

2010-11-26

11:18:37

Xxx

ServerModelC2Net

AlarmWatcher::NewAlarmService

Sending alarm event

2010-11-26

11:18:37

Xxx

ServerModelC2Net

AlarmWatcher::NewAlarmService

Alarm event sent

2010-11-26

11:19:37

Xxx

ServerModelC2Net

AlarmWatcher::NewAlarmService

Sending alarm event

2010-11-26

11:19:37

Xxx

ServerModelC2Net

AlarmWatcher::NewAlarmService

Alarm event sent

2010-11-26

11:20:37

Xxx

ServerModelC2Net

AlarmWatcher::NewAlarmService

Sending alarm event

2010-11-26

11:20:37

Xxx

ServerModelC2Net

AlarmWatcher::NewAlarmService

Alarm event sent

2010-11-26

11:20:37

Xxx

IdeaBlade.EntityModel.Server

NotificationServiceManager::AsyncNotify

Removing subscriber after error The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it has been Aborted.

2010-11-26

11:20:37

Xxx

IdeaBlade.EntityModel.Server

NotificationServiceManager::UnregisterUser

User unregistered from NewAlarmService

2010-11-26

11:20:37

Xxx

IdeaBlade.EntityModel.Server

NotificationThreadHelper::StopThread

Stopping thread for NewAlarmService

2010-11-26

11:20:37

Xxx

IdeaBlade.EntityModel.Server

NotificationServiceManager::NotificationThreadCompleted

Server method completed: NewAlarmService

2010-11-26

11:20:37

Xxx

IdeaBlade.EntityModel.Server

NotificationServiceManager::AsyncNotify

Removing subscriber after error The IOutputChannel timed out attempting to send after 00:01:00. Increase the timeout value passed to the call to Send or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout.

 

 



Posted By: danjal
Date Posted: 26-Nov-2010 at 6:09am

I changed the sleep time in LongRunningProcedure in Ideablades example like this:

 

private static void Step1() {

// Assume some logic is performed that represents 20% of the total workload.

Thread.Sleep(1000 * 5);

__notificationManager.Send(__serviceKey, new LongRunningInfo("The LongRunningProcedure is 20% done.", 20));

}

 

private static void Step2() {

// Assume some logic is performed that represents 50% of the total workload.

Thread.Sleep(1000 * 30);

__notificationManager.Send(__serviceKey, new LongRunningInfo("The LongRunningProcedure is 50% done.", 50));

}

private static void Step3() {

// Assume some logic is performed that represents 90% of the total workload.

Thread.Sleep(1000 * 40);

__notificationManager.Send(__serviceKey, new LongRunningInfo("The LongRunningProcedure is 90% done.", 90));

}

 

private static void Step4() {

// Assume some logic is performed that represents 100% of the total workload.

Thread.Sleep(1000 * 5);

__notificationManager.Send(__serviceKey, new LongRunningInfo("The LongRunningProcedure has completed.", 100));

}

 

And I got the same error in the debuglog.

 

If I change my service to send events every 5 second – then it works fine!

Further I have found out that if the frequency, where the service is sending events is somewhere between 15-20 seconds it will work fine. If it is above 15+ seconds, a timeout error will appear in the debuglog.

 

Is this some inactive timeout?

Is it possible to change it?



Posted By: smi-mark
Date Posted: 26-Nov-2010 at 10:06am
Interesting.. someone from IdeaBlade will have to chime in on this. In the mean time you could implement some sort of ping

while (true)
{
            int i = 0;
      TraceFns
.WriteLine("Sending alarm event");
      m_notificationManager.Send(m_serviceKey, new AlarmCount(1));

      TraceFns
.WriteLine("Alarm event sent");

           while (i < 6)
            {
                i++;
                 m_notificationManager.Send(m_serviceKey, PING);

                Thread.Sleep(1000*10);
             }
}

Not an elegant solution but something that may work.


Posted By: kimj
Date Posted: 26-Nov-2010 at 12:11pm
I can reproduce the problem danjal sees when using IE8.  The longer push intervals work fine in Firefox, and will probably work in Google Chrome too.  To get this working in IE8 I switched communications from the default browser stack to the client stack (in app.xaml.cs)  -
 
using System.Net.Browser;
using System.Net;
HttpWebRequest.RegisterPrefix("http://"WebRequestCreator.ClientHttp);
There's apparently a problem using the "MultipleMessagesPerPoll" setting - which DevForce uses as a default - with IE8.  The stack switch is one option, although you can't use ASP.NET security when using this.  Using "SingleMessagePerPoll" is another option, and since you likely don't need the claimed efficiencies of "multiple messages" if your notifications are relatively infrequent this may work for you.  To change this setting you do need to tweak the serviceModel settings on both client and server.  I've attached sample config files showing this.
 
http://www.ideablade.com/forum/uploads/11/Push.zip - uploads/11/Push.zip


Posted By: danjal
Date Posted: 29-Nov-2010 at 3:52am
Thank you kimj and smi-mark,
 
I used: HttpWebRequest.RegisterPrefix("http://"WebRequestCreator.ClientHttp);
And it works!!!



Print Page | Close Window