WCF Reliable Session and keep-alives

January 26th, 2009

We recently used WCF services for a monitoring application, which showed the status of business-critical systems like water/fire-detection in the datacenter, generators powering the production lines and so on. 

Instead of using a polling mechanism, we used an event-driven approach. The clients would subscribe for certain events and the server would notify the clients when these events happened. Relieving the network of excessive and possibly unneeded chatter. Because of the "business-critical" aspect of the application, we had to ensure that our communication with the server was not halted or interrupted. If something happened to the connection, the client would have to notify the user, instead of showing green lights and giving the user the impression that everything is a-ok, while all hell broke loose in the datacenter (and also destroying the PLC) for instance. Since our client would wait for events to happen and wouldn't know when the connection would have been dropped for some reason.

While working through the WCF documentation, we stumbled upon the Reliable Session which could be specified in the binding of the connection. According to the documentation a Reliable Session would send a keep-alive message after half of the Inactivity Timeout. Unfortunately the expected behaviour was not the same as the actual behaviour, the connection would go to the faulted state after 10 minutes despite configuring an Inactivity Timeout of 10 minutes. (Which should have forced a keep-alive message to be sent after 5 minutes) Eventually we came accross this blog post by Paulo Reichert, clarifying this glitch. Apparently it was supposed to work that way, but a last minute change to the Receive Timeout behaviour overrode the keep-alive behaviour. *couch* Unit Testing *couch* 

In the end we implemented our own keep-alive system in the form of a watchdog. A registry in a PLC would change every x seconds and the client would be notified of this change through an event. If our client does not detect a change of this registry for y seconds we notify the user. This ensures the connectivity between the client & server (including feedback to the user) and the proper workings of the PLC. The "keep-alive" message resets the Inactivity Timeout, prohibiting it from reaching the specified value and causing the connection to be dropped.

Setting the Receive Timeout to infinite, as suggested by Microsoft, is a work-around which does not solve the problem at a fundamental level. We sincerely hope Microsoft will fix this bug in a future release!


Welcome to our newest employee

October 20th, 2008

Sometimes, things just work out the way you wanted it to. In a world were tight deadlines, buckets of work and not enough time prevail, our newest addition to the team just walks right into the office. Behold our newest employee: Barry! Fluent in C#, years of experience with Spring.NET & NHibernate, a natural born leader, …

barry

Welcome to the team Barry, may the deadlines be with you.

PS: for the record, Barry is a girl!


B2B-Days

June 15th, 2008

b2bLast week Softelligent was present at the B2B-days in antwerp, promoting our newest masterpiece: Zintra! The responses to the demo’s we were giving at our booth were a huge success, encouraging our team to elevate Zintra out of bèta as soon as possible.

Our sales-team did an excellent job promoting our current philosophy at the fair. They created an awareness of communicating more efficiently, provided with the right soft- and hardware, all around the fair.b2b2

Thanks to everyone who came to check us out and stay tuned for the next Zintra release!


Safe Cross Thread UI Access

May 21st, 2008

When you have multiple threads running in your application and have a user interface you’ll eventually run into the fact that UI elements are only allowed to be called from the same thread they are created in. The fast workaround for this is to set the CheckForIllegalCrossThreadCalls property of your controls to false but since we’re all good developers we want to solve this in a clean way.

There is an interface to track this behaviour called ISynchronizedInvoke which defines all the methods you need, this interface is implemented by the UI controls. You need to see if the property InvokeRequired is true and call Invoke (or BeginInvoke) to make your call thread safe. I used to declare a delegate for each different method signature I encountered since the Invoke methods take a delegate as argument. But there is a much more elegant way by using the MethodInvoker delegate and an anonymous delegate as you can see below. This prevents you from declaring a lot of delegates just for making your calls thread safe. This is illustrated below by a method in a presenter which updates my view.

public void IncomingMessage(ChatMessage msg)
{
    if (m_ChatView != null && m_ChatView.InvokeRequired)
    {
        m_ChatView.BeginInvoke(new MethodInvoker(delegate
        {
            IncomingMessage(msg);
        }), new object[] { msg }); return;
    }
    m_ChatView.DisplayMessage(BuildIncomingDisplayMessage(msg));
}

MIX essentials

May 13th, 2008

A few weeks ago, the 24th of april to be exact, the Softelligent development team went to MIX essentials in Louvain-la-Neuve. The MIX essentials events are a slimmed down version of the American MIX 08 events and give an overview of what was handled on the American mainland. Luc Vandevelde was the main host and introduced the foreign and not so foreign speakers.

mix1

The event consisted of 2 tracks, one focused on development and the other on “men in suits” topics. We followed the development track which gave an introduction to Silverlight and MSN Live services and how to integrate them in your own applications.

The final keynote speaker was “Steve B” as he calls him self. The current CEO of Microsoft shared his view on IT in general and spent almost half of his time answering questions from the audience. Literally everyone was hanging on his lips, mister Ballmer is a very charismatic person. Although he didn’t perform his signature monkey dance, despite someone mentioning it during a question.

mix2

The event itself was ok, Silverlight looks pretty awesome, especially the Deep Zoom functionality. But nothing groundbraking was shown, seeing and hearing Steve B on the other hand was worth the trip anyway. I’ll probably never see someone who is richer for the rest of my life.


Minimal Lucene.Net example

April 15th, 2008

About a year ago we had to incorporate a Lucene.Net index in an application because we were unable to achieve acceptable speeds while performing regular SQL queries on a database. The database was a 4GB large – poorly normalised – full of NULLs – monster, which would eat our queries for breakfast and spit out time-outs in return. We had to make a Google-like search on the data spanning a lot of columns, including full-text search. Using Lucene.Net to index the searchable columns of this database enabled us to search the data within seconds and in some cases even work without the actual database. Because all the data which had to be shown as the result of the search could be extracted out of the index.

Lucene.Net has gained rapid exposure and several articles & tutorials can be found on how to implement it. Quite some time ago I made a minimal example on how to create an index and search it, I thought I’d share it, maybe it’ll help someone with his first steps in the Lucene.Net world.

The minimal Lucene.Net example creates an index of all the postal codes of Belgium (data is read from a .csv file), the postal codes can be searched and the results are shown in a list. Nothing more, nothing less.

Some extra information:

Analyzer analyzer = new StandardAnalyzer();

An analyzer is used when indexing raw text to transform it into searchable terms, removing frequently used words like “the”, “in”, “a”, “and”, “of”.

IndexWriter writer = new IndexWriter(indexFolder, analyzer, true);

An IndexWriter is used for creating and adding/removing items to/from the index, an analyzer should be specified which is used when adding data to the index.

Document document = new Document();
 
document.Add(new Field(POSTALCODECOLUMN, parts[0], Field.Store.YES, Field.Index.UN_TOKENIZED));
document.Add(new Field(CITYCOLUMN, parts[1], Field.Store.YES, Field.Index.UN_TOKENIZED));
 
writer.AddDocument(document);

A document is like a virtual record which contains the fields which are searchable. A field can be specified more than once, if a city has for some reason multiple postal codes, these can be added with the same field name and each time with a different postal code.

writer.Optimize();

After adding the documents the writer is optimized, which rewrites the entire index by merging all segment files into one file, greatly reducing the fysical size of the index and the searching speed.

The example is a VS2005 solution and uses Lucene.Net version 2.0.0.4 (included in the zip-file).

Minimal Lucene Example


Mystery tab #13119

April 14th, 2008

Since a couple of weeks I had this #13119 tab in the toolbox of Visual Studio. The only way I found to fix this was to go into C:\Documents and Settings\[UserName]\Local Settings\Application Data\Microsoft\VisualStudio\9.0 folder, replace [UserName] with your username, and delete the four files which have Toolbox in their name (toolbox.tbd, toolboxIndex.tbd, toolbox_reset.tbd, toolboxIndex_reset.tbd). Visual Studio regenerates these when you start it up. Full thread on MSDN can be found here.


Buildserver upgrade

April 7th, 2008

We recently started the move from visual studio 2005 to 2008 and since then our buildserver has had problems with those upgraded projects.

The first error I ran into was: File format version is not recognized.  MSBuild can only read solution files between versions 7.0 and 9.0, inclusive. Our server runs CruiseControl v1.3.0.2958 which by default targets the 2.0 framework, so you need to direct your MSBuild task to the new 3.5 version. You do this by using the executable node illustrated below:

<msbuild>
<executable>C:WINDOWSMicrosoft.NETFrameworkv3.5MSBuild.exe</executable>
...
</msbuild>

Second error: The imported project “C:Program FilesMSBuildMicrosoftVisualStudiov9.0WebApplicationsMicrosoft.WebApplication.targets” was not found. To fix this one you need to look on your development machine for that file, it’s on the same location as stated by the error if you’re using a regular install. Then go to your buildserver and recreate the same folder structure there and copy the file.

Third error: C:WINDOWSMicrosoft.NETFrameworkv3.5Microsoft.Common.targets (1734,9):  error MSB3091: Task failed because “LC.exe” was not found, or the correct Microsoft Windows SDK is not installed. The error message is larger than I’ve put here since it gives 4 ways to solve it. The easiest and probably fastest way to solve this is to download the Windows SDK for Windows 2008 and install it on your buildserver, you can find it here. It is an iso file of 1.3 GB, so make sure you have a fast connection.

Now your server has been successfully upgraded ;) .


Cleanup Folder with SDC Tasks Library

April 7th, 2008

I had to automate the deletion of the contents of a folder for one of our projects in the buildserver, one google later I ran into the SDC Tasks Library (2.1.3009.0) which had just that. The pdf file included described how to make their library available in your build script, I followed the instructions but kept running into build errors. The Cleanup task was not found by MSBuild, turned out I needed to add a trailing backslash to the path name of the TasksPath property. The final configuration is:

<!– SDC MSBuild Tools –>
<PropertyGroup>
<TasksPath>$(MSBuildExtensionsPath)\Sdc\</TasksPath>
</PropertyGroup>
<Import Project=“$(TasksPath)\Microsoft.Sdc.Common.tasks“/>
<!– SDC MSBuild Tools –>

But even with this now corrected the Cleanup folder task was not found, again I opened up their tasks file with notepad and searched for the Cleanup task, I couldn’t find it. Hmm, maybe I’m going blind so let’s use ctrl+f. Again no results. So I edited the file and put this entry to the list of tasks:

<UsingTask AssemblyFile=“$(TasksPath)Microsoft.Sdc.Tasks.dll“ TaskName=“Microsoft.Sdc.Tasks.Folder.CleanFolder“/>

Ran MSBuild again, and now successfull. For anyone who doesn’t want to edit the file, I’ve attached it.

Microsoft.Sdc.Common.tasks (40,21 kb)


Softelligent Usb-sticks

March 27th, 2008

They have arrived, so come check us out at the next event and receive your free Softelligent goody. Available in one flavour, one size fits all: Softelligent Usb-sticks with a capacity of 1GB!

usb