Websocket Research–Part 1
We are working on a major application that has the need for low-latency communication over the web. In the past we facilitated this through custom long polling or SignalR. These options were available because the platform was fixed. We are now working on an application where advanced communication across multiple platforms is required. This means websockets, not long polling. It also means binary, not just short little messages. It also means “not just Windows”. Our platform choices are iOS and Android with future growth onto other platforms. It also means .NET because that is the skillset we enjoy. Because of this we are looking at using XSockets.NET.
Stay tuned for more …
SQL Server Reporting Services, HTTP Compression, and Native Mode Installation (Part I)
SQL Server 2008 and 2008 R2 has a new mode for installing Reporting Services known as Native Mode Installation. This mode offers many benefits including simplified deployment and a reduced surface area for security. It does this by not requiring the use of Internet Information Services (IIS) to gain access to ASP.NET functionality, the Report Manager application, or the Report Server Web service endpoint. Reporting Services now does the work of hosting ASP.NET and the .NET Framework as well as leverages the capabilities of HTTP.SYS within the operating system.
So no more IIS! But wait? Doesn’t IIS offer other capabilities?
Yes, it does! One of the most needed features of IIS is HTTP Compression. This feature is tied directly to IIS and not HTTP.sys. This feature is critical to web farms where network performance is a concern. This is especially true with Reporting Services installations. So what can one do to mitigate this issue?
The recommended solution is always the one that is “in-the-box”. This means installing SQL Server Reporting Services and then configuring it to run within IIS. Unfortunately this means giving up the simple installation and deployment and increasing the surface area for attack. So what can one do?
Enter the Wicked HTTP Compression Module!
Reporting Services runs within the ASP.NET pipeline. It is possible to add support for HTTP compression using an extensibility point of ASP.NET known as an Http Module. In fact, there are plenty of Http Modules available that implement HTTP compression. One of them is the Wicked HTTP Compression Module. I wrote this module years ago and have been enhancing it ever since. I have just recently updated to support AJAX, .NET Framework 4.0, and more. Here I will show you how you can change your configuration in SQL Server Reporting Services to use this module and get back compression.
Step 1 – Download and Deploy The Wicked HTTP Compression Module Binary
I now support binary releases of the Wicked HTTP Compression Module. Download the latest Wicked Http Compression Module for .NET Framework 2.0 from CodePlex at http://httpcompression.codeplex.com/. Unzip the file and copy it over to the C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportManager\Bin directory.
Step 2 – Locate Web.Config for Reporting Services
There are many configuration files for Reporting Services. On my installation of SQL Server 2008 R2 x64 it was located under the following directory C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportManager.
Step 3 – Modify Web.Config
We will now modify the Report Manager web.config file. IMPORTANT! Make a backup of this file before you modify it.
Step 3a – Add a new entry to the configSections section.
This will tell ASP.NET that there is a new configuration section that we will be adding to the web.config file. The Wicked HTTP Compression Module has its own configuration section that we will be adding later on.
<configSections> <section name="wickedHttpCompressionModule" type="WickedProgrammer.WickedHttpCompressionSection, WickedCompressionModule, Version=4.0.0.0, Culture=neutral, PublicKeyToken=fdd99273a6f0cac9"/> <section name="MicrosoftWebControls" type="System.Configuration.NameValueSectionHandler, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" /> <section name="UIConfig" type="Microsoft.ReportingServices.UI.UIConfigSectionHandler,ReportingServicesWebUserInterface" /> </configSections>
Step 3b – Add an entry to the <httpHandlers> section.
The Wicked HTTP Compression Module comes with a tracing capability that give diagnostics on which files got compressed. To access this diagnostic, you need to first add this entry to the <httpHandlers> section and then enable tracing in the <wickedHttpCompressionModule> config section. Once done, you can access the trace through the following URL: http://localhost/Reports/WickedTrace.axd. If needed, change the server name from localhost to your server name.
<httpHandlers> <add verb="*" path="Reserved.ReportViewerWebControl.axd" type="Microsoft.Reporting.WebForms.HttpHandler, ReportingServicesWebUserInterface, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" /> <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false" /> <add verb="GET" path="WickedCompress.axd" type="WickedProgrammer.WickedHttpCompressionTraceHandler, WickedCompressionModule, Version=4.0.0.0, Culture=neutral, PublicKeyToken=fdd99273a6f0cac9" validate="false"/> </httpHandlers>
Step 3c – Add an entry to the <httpModules> section.
This will tell ASP.NET to load the Wicked HTTP Compression Module into its pipeline.
<httpModules> <clear /> <add name="OutputCache" type="System.Web.Caching.OutputCacheModule" /> <add name="WickedCompression" type="WickedProgrammer.WickedHttpCompressionModule, WickedCompressionModule, Version=4.0.0.0, Culture=neutral, PublicKeyToken=fdd99273a6f0cac9"/> <add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" />
...
<add name="ErrorHandlerModule" type="System.Web.Mobile.ErrorHandlerModule, System.Web.Mobile, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> </httpModules>
Step 3d – Add the <wickedHttpCompressionModule> section to your web.config file.
This is a required step and must be added to your config file. There are several features enabled in this config file example. First, take notice that tracing is enabled by setting enableTrace=’true’. Second, there is an excluded path specified for images. Third, there is a set of excluded MIME types. While I have done some configuration, I suspect that more will be needed. More specifically, additional MIME types will most likely need to be added. The <excludedMimeTypes> allows one to filter out any MIME types that should not be compressed. One example of this is the new Word 2007 (.docx) and Excel 2007 (.xlsx) file formats. These file formats are already compressed and should be excluded if you are downloading these types of files.
<wickedHttpCompressionModule enableTrace="true"> <excludedPaths> <!-- Example: Do not compress these pages. <add value="/nocompress.aspx" /> <add value="/image/dynamic.aspx" /> Do not compress these paths and their subdirectories. <add value="/images/" /> <add value="/files/images/" /> NOTE: The path feature assumes that all subdirectories are included. --> </excludedPaths> <excludedMimeTypes> <!-- The following MIME types are already excluded by the WickedHttpCompressionModule. JPEG Image image/jpeg GIF Image image/gif PNG Image image/png Zip File application/zip, application/x-zip, application/x-zip-compressed GZip File application/x-gzip, application/x-gzip-compressed Compressed File application/x-compress, application/x-compressed --> <add value="application/octet-stream"/> <add value="application/pdf"/> </excludedMimeTypes> </wickedHttpCompressionModule>
Step 4 – Modify rsmgrpolicy.config
Reporting Services has its own policy files. We need to modify the policy file to allow the WIcked HTTP Compression Module to execute. In this situation, we put a new code group right after the Microsoft_Strong_Name code group.
<CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust" Name="Microsoft_Strong_Name" Description="This code group grants code signed with the Microsoft strong name full trust. "> <IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293" /> </CodeGroup> <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust" Name="WickedHttpModuleCodeGroup" Description="Code group for Wicked HTTP module"> <IMembershipCondition class="UrlMembershipCondition" version="1" Url="C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportManager\bin\WickedCompressionModule.dll" /> </CodeGroup>
Step 5 – Stop and Start Reporting Services using the Reporting Services Configuration Manager
Almost Done! Now all that is needed is to stop and start Reporting Services using the Reporting Services Configuration Manager.
Thoughts On BlogEngine and Arthemia Pro Theme!
After spending several weeks on BlogEngine, I can honestly say that it a usable engine that I really enjoy working with. However, BlogEngine is showing its age and its history a bit much. IMHO, it should be rewritten for .NET Framework 4.0 from the ground up. IMHO, one of the best themes for BlogEngine, Arthemia Pro has a great look to it, but is a port from another engine and has significant issues with the code. This article will discuss my findings when working with BlogEngine and the Arthemia Pro Theme. There will be no order to the various areas.
Arthemia Pro Theme
This blog uses the Arthemia Pro Theme for BlogEngine. Originally I picked a port of the Arthemia theme for WordPress from Onesoft. This theme looks OK, but was riddled with bugs. So I moved to the Arthemia Pro theme. Unfortunately that theme leveraged the same Arthemia theme as its base and didn’t correct any of the bugs. In fact, it probably introduced a few. Thanks to Visual Studio 2010 and Intelltrace and I was able to quickly eradicate several bugs with this theme. Most of them were links pointing to the wrong path for some .js and image files. However, there were some long time bugs like the headline and features not showing up that was just painful to troubleshoot. Thanks again Intellitrace.
The Arthemia and Arthemia Pro themes tend to use code as a mechanism for updating things like ‘About Me’. My hope is to change this to be more inline with what people expect these days. This should be some form of editable widget or web part.
Asynchronous Work
BlogEngine likes to do a ton of asynchronous work. For example, it has an AutoSave feature in the admin pages and a Ping Service notification feature.
SendPing Extension
First, let me tackle the Ping Service notifications. Here is an actual block of code. Notice it goes to sleep? Wow! I have no words for this.
System.Threading.Thread.Sleep(2000); // Ping the specified ping services. BlogEngine.Core.Ping.PingService.Send(itemUrl);
One other thing, if this feature were to fail, it will never try again. I call this the ‘Best Effort’ approach. Unfortunately its best effort is not so good. If it fails, an exception will occur and then be trapped.
AutoSave
Every blog needs this feature! Unfortunately it sends stuff every 5 seconds. Turning this down a few notches requires code though. I set mine to every 60 seconds. Also, this feature integrates with the Ping Services to send updates whenever a new blog is published.
Database Access
OMG! BlogEngine is the Chatty Cathy of blogging engines! This thing goes to the database a gazillion times at startup. It even writes back to the database at startup! Why would it ever need to do this?
BlogEngine uses a combination of browser, full page, and data caching to achieve any type of acceptable performance. This is one of the best aspects of this engine! However, I am concerned of the performance over time when you have a large number of posts. Does startup performance degrade? What happens if you have a popular blog and it has tons of page views and everything is always kept in-memory? Better yet, what about moving to a cloud architecture where every database transactions may cost money?
Caching should not be used as a bandaid to a poor performing data access layer. IMHO, there needs to be an overhaul of the data access layer.