Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Increasing the Lifetime element for EWS Streaming Subscription Connection

Using Microsoft's EWS, we're able to listen to a mailbox and take actions when a new email comes in. However, I can't figure out how to avoid the connection timing out.

Per Microsoft, here is the constructor for a StreamingSubscriptionConnection:

public StreamingSubscriptionConnection (
    ExchangeService service,
    int lifetime
)

In my app, I've coded it as follows:

service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
StreamingSubscriptionConnection conn = new StreamingSubscriptionConnection(service, 30);

In other words, I've got the timeout (lifetime) set to 30 minutes, because that's the highest I've been able to set it. How can I increase this? Or, how can I trick this subscription into staying alive, even if ~45 minutes transpire between incoming emails?

like image 236
WEFX Avatar asked Jun 16 '11 18:06

WEFX


3 Answers

30 minutes is a hard limit. You can not change it to a higher value.

To solve this issue, wire up a handler to the OnDisconnected handler of the OnDisconnect event of the connection instance. Restart the subscription from there (just call connection.Open() from that handler).

like image 54
Henning Krause Avatar answered Oct 21 '22 17:10

Henning Krause


If anyone else is interested, this is how I am accomplishing this.

I want to keep the connection open, so I am resetting it in the OnDisconnect handler.

However, before resetting it, I check the private "subscriptions" dictionary on the connection object using reflection.

This allows me to unsubscribe from my connections elsewhere in my code (OnNotificationEvent), and when all subscriptions have been unsubscribed from, I am then able to close the connection.

Here is my Code:

 void connection_OnDisconnect(object sender, SubscriptionErrorEventArgs args)
    {
        var c = (Dictionary<string, StreamingSubscription>)typeof(StreamingSubscriptionConnection).GetField("subscriptions",System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(sender);

        if (c.Count > 0)
        {
            // reopen the connection
            ((StreamingSubscriptionConnection)sender).Open();

            using (var db = new Metrics_DatabaseEntities())
            {
                PushNotificationTest pt = new PushNotificationTest();
                pt.RetObj = "Connection reset";

                db.PushNotificationTests.Add(pt);

                db.SaveChanges();

            }
        }
        else
        {
            using (var db = new Metrics_DatabaseEntities())
            {
                PushNotificationTest pt = new PushNotificationTest();
                pt.RetObj = "Connection closed!";

                db.PushNotificationTests.Add(pt);

                db.SaveChanges();

            }
        }
    }

Please disregard the poor way that this is written, this is just my first version, as I plan to write this more cleanly soon. I just thought I would share my methodology with folks that might be interested.

like image 41
Stevio54 Avatar answered Oct 21 '22 17:10

Stevio54


If people are interested, here's the little bit of logic that got added.

I added this to my Start method:

conn.OnDisconnect += 
    new StreamingSubscriptionConnection.SubscriptionErrorDelegate(OnDisconnect);

I then added the OnDisconnect method:

private void OnDisconnect(object sender, SubscriptionErrorEventArgs args)
{
    Start();
}

Ultimately, this still needs improved, because this simply times-out and reconnects every half-hour, regardless of incoming email activity. I'd rather get something in place that resets the counter every time a new message comes in. Then, it would only time-out a couple times per day, instead of 48! Still, this is serving its purpose of keeping my email-listening program online.

like image 41
WEFX Avatar answered Oct 21 '22 15:10

WEFX