JavaScript Saturday premiers in Long Beach

Michael PhillipsIf you’re in the Los Angeles area you can come see us on our latest world tour stop at JavaScript Saturday in Long Beach this very Saturday, November 10th!

We’re bringing this guy with us to make his tour debut and check out the sessions. Come and say hello, and get into the Long Beach JavaScript groove (reportedly the best groove available on Saturday).

According to the organizers, JavaScript Saturday is a complete one-day Training from the best of the Javascript experts aimed at all levels of expertise.

Have no experience in Javascript? – Go from beginner to advanced in a day.

Want to know about Javascript frameworks and how to advance in your career – This event is for you.

Victim of Information overload? – You will know what you need to know and you will find out what you don’t know.

Speakers
Nathan Totten – Microsoft
Chander Dhall – Microsoft MVP, author, trainer, mentor
Hattan Shobokshi – Microsoft Community Contributor, Speaker & Senior Software Engineer
Jeff Carlos – Co-founder/CTO Triplark.com
Troy Miles – designer and developer of software since 1979, mobile development team at Kelley Blue Book
Jason Beres – VP of Product Management, Community, and Developer Evangelism

One state, two state, red state, blue state

Michael PhillipsFour years ago we showed you a Presidential election map and a nifty pie chart demonstrating a pretty close correlation between the percentages of the electoral votes and our American customer distribution.

Florida is still too close to call as they like to say, but even without it, you can see that our customer distribution continues to correlate pretty closely with the electoral vote distribution. We were six points away in 2008, and we’re about 8 points away this year. That could change depending on which way Florida flips.

Compared to 2008, you can see that we have slightly more customers in “red” (electoral votes went to the Republican candidate) states than “blue” (electoral votes went to the Democratic candidate) states, and – wouldn’t you know it –  there were more electoral votes from red states this year.

What does that tell us? I don’t know if it tells us much of anything, but it’s a good excuse to put up a cool map. 😉

One state, two state, red state, blue state

Michael PhillipsFour years ago we showed you a Presidential election map and a nifty pie chart demonstrating a pretty close correlation between the percentages of the electoral votes and our American customer distribution.

Florida is still too close to call as they like to say, but even without it, you can see that our customer distribution continues to correlate pretty closely with the electoral vote distribution. We were six points away in 2008, and we’re about 8 points away this year. That could change depending on which way Florida flips.

Compared to 2008, you can see that we have slightly more customers in “red” (electoral votes went to the Republican candidate) states than “blue” (electoral votes went to the Democratic candidate) states, and – wouldn’t you know it –  there were more electoral votes from red states this year.

What does that tell us? I don’t know if it tells us much of anything, but it’s a good excuse to put up a cool map. 😉

A Presidential WebSockets Project

Michael OssouIf you are anything like me, watching the Presidential Debates was an exercise in not being distracted by the “dial-o-meter” at the bottom of the screen.

Since the two biggest features of HTML 5 are Canvas and WebSockets, I thought a Dial-o-Meter would lend itself well to a simple sample project that pretty much anybody could follow along with.

So in this post, we are going to build the “Dial” using Canvas and WebSockets. Maybe in a future post we will upgrade and complete the project, using SignalR.

First some prerequisites. Since we’ll be using the final release of ASP.NET 4.5, there is no need to use any Nuget package. We will be concentrating on the System.Web.WebSockets namespace.

WebSocket support is only available in ASP.NET 4.5. This means you will need to be on IIS 8. If you have not yet migrated, you will need to do so (In the Account Information section of Control Panel, look for “Server Type” and you can find an UPGRADE link there). If you are already on an IIS 8 account, we will need to make sure your account is ready for WebSockets. Contact support and they can make the necessary WebSockets configuration for you.

It’s also important to note that if you are running Visual Studio 2012 on Windows 7, the application will not run locally. You will need to work on the application, then upload it to the server to run it. This is because WebSockets will only run on Windows 8/Windows 2012. On the client side, you will need a browser that supports HTML 5.

So whats the point of all this? The short version is that the WebSocket protocol provides us with the plumbing to maintain a persistent, two-way, communications channel between the client and the server. This is ideal for applications that require real-time updating. The most common use cases described are things like chat or a stock related application. With the plumbing here however, it wont be long before people turn to WebSockets for a host of other things as well.

Using WebSockets is much faster than servicing HTTP requests. This means using WebSockets could be a better solution than AJAX for large dynamic applications. So how do WebSockets Actually Work? You can look here for the details, but essentially an HTTP request is made and that connection is upgraded to a WebSocket connection.

With all of that out of the way, let’s dive in and start with our HTML Page. There are two buttons to indicate Up/Down emotions that trigger messages to be sent to the server. There is also  a canvas that will visually display the data that is returned from the server. For this post/sample, all we are doing is making a round trip.

Screenshot of the WebSocket Dial we are building

Instead of the buttons affecting the canvas on the page directly, we will instead use WebSockets to send the data to the server, and have the server send the data back to the browser. Then, the canvas will be updated based on the server data. We do all this on the client side using JavaScript.

The entire project is included at the bottom of the post, but lets look at it section by section.

First the HTML controls. Nothing fancy here. The controls that we already talked about above and a place holder we will use to echo network communications.

<canvas id="myCanvas" width="800" height="400"></canvas>

 <input id="btnUp" value="Up" type="button" />
 <input id="btnDown" value="Down" type="button" /></pre>
<div id="dvNetworkStatus"></div>
<pre>

Now for the Heart of the page, lets look at the JavaScript that ties into the browsers API’s and makes all this work for us. Again, one section at a time.

Here we are defining our WebSocket endpoint and tying up the websocket object that is exposed to us to some custom functions.  When the WebSocket connection is opened, closed, or we receive a message from the server, we want a specific function to be fired.

<script type="text/javascript">// <![CDATA[
              $(document).ready(function () {

                  var wsUri = "ws://iis8hosting.com/websocketblog/wshandler.ashx";
                  websocket = new WebSocket(wsUri);
                  websocket.onopen = function (evt) { onOpen(evt) };
                  websocket.onmessage = function (evt) { onMessage(evt) };
                  websocket.onclose = function (evt) { onClose(evt) };
                  websocket.onerror = function (evt) { onError(evt) };

With our WebSocket object setup, lets get the canvas ready. We setup the canvas object then initialize it. The reason we initialize it in its own function is because we will want to clear it out later again when it gets full. So we put that piece in its own function so we can just call it again later. The canvas works with an X/Y coordinate system so we want to initialize those values as our baseline as well.

                  var canvas = document.getElementById('myCanvas');
                  var context = canvas.getContext('2d');
                  var xCoordinate = 10;
                  var yCoordinate = 200;
                  initCanvas();

                  function initCanvas() {
                      canvas.width = canvas.width;
                      context.fillStyle = "#78829E";
                      context.fillRect(0, 0, 800, 400);
                      context.beginPath();
                      context.strokeStyle = 'white';
                      context.moveTo(0, 200);
                      context.lineTo(800, 200);
                      context.stroke();
                      xCoordinate = 10;
                      context.beginPath();
                      context.moveTo(xCoordinate, yCoordinate);
                      context.strokeStyle = 'black';
                  }

The next set of functions correspond to various states of our WebSocket connection as defined up top. Notice all we are doing with them now is updating our little status place holder. Also, notice the wsSend function. This is the function responsible for actually sending the data across the wire.  The onMessage function is fired when we receive a message from the server. Notice it calls the drawToCavas method to update the line on our canvas.

                  function onOpen(evt) {
                      $('#dvNetworkStatus').text("Server Status: Connected");
                  }

                  function onMessage(evt) {
                      $('#dvNetworkStatus').text("Message Recieved: " + evt.data);
                      drawToCanvas(evt.data);

                  }

                  function onClose(evt) {
                      $('#dvNetworkStatus').text("Server Status: Closed");

                  }

                  function onError(evt) {
                      $('#dvNetworkStatus').text("Server Status: Error Connecting USE FIDDLER TO DEBUG!!!!");

                  }

                  function wsSend(message) {
                      $('#dvNetworkStatus').text("Message Sent: " + message);
                      websocket.send(message);
                  }

Next up is our drawToCanvas function. We make sure our X/Y coordinates are within the bounds of our canvas, if they are not, we call the initCanvas function descibed above to give us a clean slate. Then we simply draw the line onto the canvas.

                  function drawToCanvas() {

                      // If we get close to the edge of the canvas, clear and start over.
                      xCoordinate = xCoordinate + 25;

                      if (xCoordinate > 740) {
                          initCanvas();
                      }

                      context.lineTo(xCoordinate, yCoordinate);
                      context.lineCap = 'round';
                      context.lineWidth = 6;
                      context.stroke();
                  }

Lastly, the two functions responsible for our button clicks. Now this could have been one function but lets keep things simple. The key thing to note here is that the clicks are calling the wsSend function mentioned above and passing the updated yCoordinate.

                  $('#btnUp').click(function () {
                      if (yCoordinate > 25) {
                          yCoordinate = yCoordinate - 25;
                      }

                      wsSend(yCoordinate);
                  });

                  $('#btnDown').click(function () {
                      if (yCoordinate < 375) {
                          yCoordinate = yCoordinate + 25;
                      }
                      wsSend(yCoordinate);
                  });

              });

// ]]></script>

That’s it for the client side. Now on to the server. We are going to create a generic handler and use Async & Await to service the requests. Again, step by step. First, we need to make sure that the request coming in is indeed a WebSocket request. If it is, our async task called MyWebSocketTask will service the request. This is where we accept/upgrade our connection request. If its not, throw an exception.

    public class wshandler : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            if (context.IsWebSocketRequest)
            {
                context.AcceptWebSocketRequest(MyWebSocketTask);
            }
            else
            {
                throw new HttpException("This isn't a WebSocket request!");
            }

        }

Here is our brain. We are going to wait for a message, then simply echo that message back to the client.

        public async Task MyWebSocketTask(AspNetWebSocketContext context)
        {
            WebSocket socket = context.WebSocket;

            while (true)
            {
                ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]);

 // Asynchronously wait for a message to arrive from a client
 WebSocketReceiveResult result =
 await socket.ReceiveAsync(buffer, CancellationToken.None);

 // If the socket is still open, echo the message back to the client
 if (socket.State == WebSocketState.Open)
 {

 string userMessage = Encoding.UTF8.GetString(buffer.Array, 0,
 result.Count);

 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMessage));

 // Asynchronously send a message to the client
 await socket.SendAsync(buffer, WebSocketMessageType.Text,
 true, CancellationToken.None);
 }

 else
 {
 break;
 }
 }
 }

That’s all there is to it. I hope this gave you an idea of where you can go with WebSockets. Maybe all the way to 1600 Pennsylvania Avenue…

Download the entire project here.

Why we have mass emailing policies in place

Michael PhillipsA lot of individuals and businesses have legitimate reasons to send out large amounts of email. We understand that, but we still maintain a relatively small quota for mass email (1,000 per hour, 5,000 maximum per day). So a question we often hear is “What’s up with that, you stingy, mail quota having so-and-so?”

Here’s what’s up with that

There are a few reasons for the quotas. First, our email servers and gateways serve tens of thousands of users with hundreds of thousands of email accounts. If we didn’t have an hourly limit we would run into severe bottlenecks that would degrade service for everyone. Imagine a mere 40 or 50 users each dumping 10,000 messages into the queues at the same time. Your single email to a client somewhere would have to wait for hours to be delivered behind an avalanche like that.

You might reasonably suggest, “Hey, if that’s the case, just add more servers!” But every network has limits. We could add a thousand email servers, but there would still be a theoretical choke point at the network level. If it was simply a question of adding more servers, email giants like Google and Yahoo wouldn’t have sending limits. But they do, for more or less the same reasons we do.

Spam

Then there is spam. We have very stringent fraudulent account prevention measures in place. But occasionally a bad apple does slink through. Typically within minutes of the account being set up, email starts to flow. Spam email. Our rate limiters kick in and say, “Hold on there, sport, you can’t do that,” and we avoid allowing a large amount of spam to escape.

That’s important because when a large amount of spam escapes, very bad things happen, including the blacklisting of mail and mail gateway servers. Blacklists effectively cut off a server from delivering to the outside world. Different blacklists have different effects, and some are worse than others, but none of them are good.

We have a pretty speedy team here that takes care of blacklisting, but there is still a negative impact on email service for those servers while we get them de-listed. And as any farmer can tell you, it’s better to close the barn door before the cows get out and run wild. If cows can run wild. I think they can, according to old cowboy movies.

A sterling reputation

Finally, there is something called server reputation. This is an important thing. When you set up a new email server with a new IP address, the big recipients (Google, Yahoo, AOL, large ISPs) all see messages coming from a new IP and say, “I’ve never seen that server before, let’s make sure this is legit,” so they pay very close attention to the messages.

Every large recipient has their own way to calculate server reputation, but the gist of it is the same everywhere. They “grade” the server according to spam complaints registered by their own users. That negative feedback can affect the server’s reputation, especially when a server is relatively “young.” The more “clean” messages that go out, the better the server’s reputation.

The better the server’s reputation, the less likely that legitimate messages will wind up in a recipient’s junk, trash or spam folder. But even a server with a very good reputation can be penalized by one large spam incident, so you can see why it’s important to protect that reputation.

So in a nutshell

Our primary goal is a seamless and trouble free service for every one of our users. Sometimes providing that experience comes at the expense of allowing certain things. Mass emailing is one of those things. So if you have a need to send out a large amount of mail on a regular basis, we recommend using a third-party mailing service. There are a lot of them out there, from commercial web-interface services like Constant Contact, to API-based services geared more toward developers, like Mailgun and SendGrid.

Win a FREE ticket to Javascript Saturday

Michael PhillipsWe’re sponsoring and giving away free tickets to Javascript Saturday in Long Beach, CA on November 10th!

Javascript Saturday is a complete one-day Training from the best of the Javascript experts aimed at all levels of expertise.

  • Have no experience in Javascript? – Go from beginner to advanced in a day.
  • Want to know about Javascript frameworks and how to advance in your career – This event is for you.
  • Victim of Information overload? – You will know what you need to know and you will find out what you don’t know.

Speakers
Nathan Totten – Microsoft
Chander Dhall – Microsoft MVP, author, trainer, mentor
Hattan Shobokshi – Microsoft Community Contributor, Speaker & Senior Software Engineer
Jeff Carlos – Co-founder/CTO Triplark.com
Troy Miles – designer and developer of software since 1979, mobile development team at Kelley Blue Book
Jason Beres – VP of Product Management, Community, and Developer Evangelism

Here’s your chance to win a free ticket.

The contest is open for entries until Tuesday, November 6th. You can enter every day, and when you share the contest on Facebook you get three additional entries every time one of your friends enters!

Will DiscountASP.NET users purchase a Microsoft Surface?

Stefanus HadiBoth Microsoft CEO Steve Ballmer and Windows Division President Steven Sinofsky were present on a Hollywood stage to showcase a new tablet computer unveiled as Microsoft Surface in Los Angeles on June 18, 2012. An invitation to the event was sent out to the journalists with very short notice.

While many considered the Surface strategy as Microsoft’s answer to the iPad, the pre-order of the device started last week with the basic Windows RT model at $499 per unit.

Previously I blogged about whether our customers would upgrade to the Windows 8 O/S, and for this post we look at our customers interest in purchasing the Microsoft Surface which will officially launch tomorrow, Friday, October 26, 2012.

In a recent customer survey we asked our clients to answer “yes” or “no” to their intention to purchase the Surface Tablet. We received 1,265 responses from around the world and 822 of the responses were from the U.S.  Just as in my previous post, we’ll limit the range of samples by pulling data from only our U.S.-based customers.

The survey results show that 51% of our customers in the US will purchase a Microsoft Surface.

In my previous post we observed that 60% of our U.S.-based customers indicated that they would upgrade or purchase the Windows 8 O/S (see plot below). It appears that a large percent may get Windows 8 through the purchase of the Microsoft Surface.

We also asked our customers which mobile phone they used and the customers who answered “yes” to wanting to purchase a Microsoft Surface were using the iPhone at 39% and Android at 41%.

From our previous post, we observed that among those that intended to upgrade to or purchase Windows 8 had a higher percentage of iPhone (47%) and Android (53%) adoption compared to those customers that wanted to purchase the Microsoft Surface.

However, one of the interesting observations was that our customers who answered “yes” to Surface used the Windows Phone at 39% while customers who answered “no” used the Windows Phone at 7%.  This indicates that our customers who have invested in Microsoft devices remain loyal to Microsoft products.

In summary, there is no doubt that our customers will continue to invest in Microsoft products.  With half of our customers interested in purchasing the new Microsoft Surface, this supports Microsoft’s claims that they have been overwhelmed with Surface pre-orders since last week.  Not to mention a Bill Gates video interview where he talks about his excitement over the new form factor has been posted.

We see that a large percentage of our customers who use the Windows Phone are also attracted to the Microsoft Surface which suggests one avenue for Microsoft to market the Surface. However the question remains how the new device will fare in attracting a new generation of users that may not necessarily use Microsoft products and who may already own an iPad or Android tablet.

The other open question is about the application ecosystem for the new device which will be critical for its success. While the Microsoft application ecosystem does have a lot of catching up to do, this is a great opportunity for our customers to think about and build Windows 8 applications and contribute to this ecosystem.

I’m sure we will see a lot of Microsoft activities around building Windows 8 apps for a while. Windows 8 and Surface are critical products for Microsoft and we will continue to see how these products are being adopted by our customers.

TFS Process Template Upgrade TF51515 Error

Joseph JunTeam Foundation Server 2012 Journal Entry: Day 43:

Deploying Team Foundation Server 2012 in our hosting environment at our North American and European data centers has been successful. All services have been stable and I’m seeing a decent rate of new customers that are early adopters.

I have performed several free migrations for our existing Team Foundation Server 2010 customers to the new environment. Everything has been working well, but a handful of users have been reporting a problem.

While the Team Project Collection and associated Team Projects and data have moved over, using the Configure Features wizard results in an error: “TF51515: The constant ID for InsertConstantSet is missing.”

Scouring the error code produced no useful information and I enlisted the help of the Microsoft Visual Studio Team Foundation Server 2012 team. It had been several weeks since I had first contacted them but I’m happy to have found a workaround.

The information that I had gathered was: In some cases, if a Team Project contains a custom Team Project Group, the Configure Features wizard (feature enablement) that upgrades a previous Process Template to an updated version shipped with Team Foundation Server 2012 that allows the use of new features, it will fail and throw the TF51515 error.

Having performed a serious evaluation, I have discovered that there are certain requirements that must be met in advance:

  • You must be a member of the Project Collection Administrators group.
  • You must have the updated tools that are compatible with Team Foundation Server 2012 that are available after you install Visual Studio 2012 or Team Explorer for Visual Studio 2012.
  • You should make sure that you can run Command Prompt with elevated privileges.

If the requirements are met, the following steps need to be performed:

  1. Make sure that no team members are actively making changes.
  2. Create a backup (If you are a TFS 2012 hosting customer, please contact our technical support team and we can create an in-place backup on your behalf).
  3. Obtain the unmodified Work Item Templates. Download: TFS2012TypeDefinitions.zip.
  4. Extract the contents of the TFS2012TypeDefinitions.zip file and note the location.
  5. For good measure, delete the cache directory at: C:\Users\WindowsUser\AppData\Local\Microsoft\Team Foundation.
  6. Before going any further, just note that you’ll have to repeat the steps below for each Team Project that is failing to upgrade. Just work with the first Team Project that you’re having problems with.
  7. Access the witadmin command-line tool:
    • Visual Studio 2012: Open Developer Command Prompt for VS2012
    • Team Explorer (x86): Open a Command Prompt window with elevated privileges and change directories to: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE>
    • Team Explorer (x64): Open a Command Prompt window with elevated privileges and change directories to: C:\Program Files\Microsoft Visual Studio 11.0\Common7\IDE>
  8. Execute the following command to get a full list of Work Item Templates for your Team Project: witadmin listwitd /collection:https://TfsServer.discountasp.net:443/tfs/YourTeamProjectCollection /p:”YourTeamProject”
    I would highly recommend saving the list to a separate text document.
  9. Even though a backup is available, as an extra precaution, create a backup of each existing Work Item Template. To download the Work Item Template, execute the following command for each Work Item Template: witadmin exportwitd /collection:https://TfsServer.discountasp.net:443/tfs/YourTeamProjectCollection /p:”YourTeamProject” /n:”WorkItemTemplate” /f:”C:\path\WorkItemTemplate.xml.bak”
  10. Execute the following commands:
    • Task Work Item Template: witadmin importwitd /collection:https://TfsServer.discountasp.net/tfs/YourTeamProjectCollection /p:”YourTeamProject” /f:”ExtractedZipFilePath\ProcessTemplate\task.xml”
    • Code Review Request: witadmin importwitd /collection:https://TfsServer.discountasp.net/tfs/YourTeamProjectCollection /p:”YourTeamProject” /f:”ExtractedZipFilePath\ProcessTemplate\CodeReviewRequest.xml”
    • Code Review Response: witadmin importwitd /collection:https://TfsServer.discountasp.net/tfs/YourTeamProjectCollection /p:”YourTeamProject” /f:”ExtractedZipFilePath\ProcessTemplate\CodeReviewResponse.xml”
    • Feedback Request: witadmin importwitd /collection:https://TfsServer.discountasp.net/tfs/YourTeamProjectCollection /p:”YourTeamProject” /f:”ExtractedZipFilePath\ProcessTemplate\FeedbackRequest.xml”
    • Feedback Response: witadmin importwitd /collection:https://TfsServer.discountasp.net/tfs/YourTeamProjectCollection /p:”YourTeamProject” /f:”ExtractedZipFilePath\ProcessTemplate\FeedbackResponse.xml”
  11. Use Internet Explorer to access the Team Project Collection Overview page at: https://TfsServer.discountasp.net:443/tfs/YourTeamProjectCollection/_admin, select the Team Project and then click Configure Features.
  12. Go through the steps in the wizard and your older Process Template should update.

I have been informed that the problem is a bug and Microsoft will issue a formal fix in the first quarter of 2013.

Thanks to Bogdan Spaiuc and Aaron Hallberg over at Microsoft for giving us a hand with this issue.