Book Image

SignalR: Real-time Application Development - Second Edition

By : Einar Ingerbrigsten
Book Image

SignalR: Real-time Application Development - Second Edition

By: Einar Ingerbrigsten

Overview of this book

Table of Contents (19 chapters)
SignalR – Real-time Application Development Second Edition
Credits
About the Author
Acknowledgments
About the Reviewers
www.PacktPub.com
Preface
11
Hosting a Server Using Self-hosted OWIN
Index

Preface

This preface gives you a look at what this book consists of, conventions and details about downloading, and more. In addition, it establishes a common understanding, setting the theme for the rest of the book. It walks you through the history of application development, especially that of web applications.

The topics that will be covered are as follows:

  • Why we need to think differently about our applications and how they relate to a server

  • The different techniques that can be used without something like SignalR

  • The protocols and techniques that SignalR uses to do what it does

  • Why we need something like SignalR

  • What UX improvements one could have in an application when applying SignalR

At this stage, the developer should have a basic knowledge of how SignalR works and what the developer needs to rethink when designing applications that have a persistent connection to the server.

The emperor's new clothes

As with fashion, it sometimes feels like history repeats itself in our industry as well. It seems that we have come full circle with how software should be architected. I guess this comes from having pretty much the same goal; software solutions that are available to a lot of users and keep the data as updated as possible for all users. What this means is that we probably want to have a shared data source from where all clients can get their data. It also means that we need some kind of network connection for the clients to connect to the centralized data source. The clients are typically distributed across multiple offices, maybe even different geo-locations. With different geo-locations often comes the challenge of different network types and bandwidth.

The good old terminal

Before we get in to the cool stuff, it's important to gain some perspective on the problem we're trying to solve. It is, in fact, a real problem dating back to the early days of computers.

Back in the 1970s, in the early days of computers, it was quite common to see terminals in offices much like the one shown in the following image:

The nature of these terminals was to be as dumb as possible. They didn't do any computation, nor did they hold any state. The terminal only reflected what the server wanted the terminal to show on screen, so in many ways they were just really fancy television sets. Any input from the user's keyboard was sent to the server, and the server interpreted the user input, updated the users' terminal session, and sent the screen update back to the terminal, as shown in the following diagram:

This model proved very helpful; technically, we, as developers, had everything on our server and didn't have to think about any rich clients holding stakes and making it all the more complex. We only needed to scale the server, and potentially deal with multiple servers and keep them in sync, or work against a centralized data source. However, it didn't prove useful for a good user experience. The terminals were limited to text only, and the types of user interface one could create were limited, often ending up being very data-centric and keyboard-friendly.

X Server

The X Window system (commonly known as X11) came in 1984, originating at the Massachusetts Institute of Technology (MIT). It was a graphical user interface system. With it came a network protocol to enable networked computers to connect to servers in a similar fashion as the terminals of the '70s, but, with its graphical capabilities, it was a big step up from the text-based terminal.

As with the terminal solution, the users' input was to be sent to a server, and the software the user used would, in fact, run on that very server. The result in the graphical user interface would then be sent back to the client machine, as represented in the following figure, again leaving the client to be rather dumb and passive:

Remote desktop

Meanwhile, in the world of Windows, in 1998, Windows NT 4.0 got a new edition of the operating system: Terminal Server Edition. With this edition, Microsoft introduced a new protocol called the Remote Desktop Protocol (RDP). It enabled the client to view another computer's desktop. With NT4 Terminal Server, the operating system was able to host multiple desktops for multiple users at the same time. From this remote desktop, clients could then launch any application they wanted that existed on the server they were connected to. As with the good old terminals, the client computer did not need to be very capable. In fact, this turned out to give birth to an industry, Think Client computers, capable of connecting to RDP-enabled servers, as shown in the following block diagram:

Rich clients

Running the software on the server puts tremendous pressure on the server and its capability. The server must be capable of handling all the users and their inputs, which leads to the need for a certain computational power; of course, depending upon the application itself.

Sometimes it does not make any sense to have everything running on a server. It might not be worth it for your particular application, or it might be too costly to try to scale for what you need. It can also be a question of responsiveness; your app might need more responsiveness to make sense to the user. However, taking the step into the world of a rich stateful client normally increases the complexity of our solutions, depending on what we're making.

If we do not have any concurrency issues or data that has become stale, we don't necessarily have any issues that need to be solved. Unfortunately, for most lines of business software out there, this is not the case. We need to take into consideration that there might be multiple users out there, and decide on how to deal with them. We can go down the optimistic path and pretend that the users seldom run into each other's data and we just overwrite any data that we might have modified while we were making a change in the same piece of data. We could also go pessimistic and not allow that at all, which would give us an exceptional state in the application that we often let our users deal with. This way, we can let the rich clients deal with this and pretty much leave the problem behind and use something like TCP sockets and communicate among the clients as they are changing the state. The other respective clients can then pick up the change and alter their own state before the user saves theirs. They can even notify the user that someone else has modified it.

The Web

Here we are again, back to the dumb client. Our web browsers have served as the passive client for years. The model is frighteningly similar to the terminal solution of the '70s; a dumb client capable of taking input and rendering whatever comes across the network, and a rich server doing all the work.

Hypertext Transfer Protocol (HTTP) is what makes up the Web. It surfaced for the first time in 1991 and basically describes a protocol for making a request to a server and the server sending a response back. The protocol is stateless and you will need to keep the state either on the server or the client. Within the protocol there are well-defined verbs that can be used, such as POST, GET, PUT, DELETE, and many more. These verbs let us describe what we are doing. However, a well-defined and rich protocol has nothing defined in it to let the clients be persistently connected. You can read more about HTTP at http://en.wikipedia.org/wiki/Http.

As the capability of web browsers has increased over time, we've watched them go from being very passive to rich clients. The mid 2000s gave us the buzz often referred to as Web 2.0 and AJAX (Asynchronous JavaScript and XML). At the core of this JavaScript was something called XHR (XMLHttpRequest), making it programmatically possible to call the server from the client without any user interaction. This technique leverages HTTP, and you find yourself getting parts or even the data instead of getting whole web pages. You can put the data into the already-rendered web page. You can find more details about AJAX at http://en.wikipedia.org/wiki/Ajax_(programming).

Modern web applications are turning into a hybrid of rich clients and thin clients; very capable, but they shouldn't do it all – we also need the server-side logic. A true step in the right direction is letting the client be good at its forte and doing likewise with the server, thus separating the concerns of the two tiers.

Now that we have all this power in the browser, we quickly run into similar problems as those we run into with regular rich clients, that is, states on the client.

Full duplex on the Web

With the evolution going back to where we started from, meaning that we are now at a point where we need the same kind of connectivity that we needed for rich desktop applications in the past, but now the demand is that applications go live on the web. With user demand come technical challenges: the web is not built for this; the web is based on a request/response pattern. The browser goes to a specific URL and a server generates a resource.

One of the things that the W3C organization has done to accommodate this need is the standardization of something called WebSocket: full-duplex communication channel over a single TCP connection. A very good initiative is something that will be supported by all browser vendors as well as web servers. The challenge, with it getting a broad adoption, is on the infrastructure that makes up the Web. The entire infrastructure has been optimized for the request/response pattern, and a steady connection establishes a point-to-point connection between two computers, and all of a sudden scalability becomes an issue. So in many cases, this might not be the best solution.

Events

Another initiative called server-sent events was implemented by Opera, the Norwegian browser vendor, which is now being standardized by W3C. It gives us the opportunity to push events from the server to the clients that are connected. On combining it with the regular HTTP request/response, we are able to meet the requirements of rich applications. You can read more about server-sent events at http://en.wikipedia.org/wiki/Server-sent_events.

Comet

Not changing the subject just yet, a technique called Comet has also been applied with great success. The basic principle is to utilize something called long polling HTTP requests. One opens an HTTP request to the server from the client, and the server does not return anything until it has something to return, like an event that happens on the server. When the response has been given, the client starts a new long polling connection and keeps on doing so for ever. This simulates a full-duplex connection and scales very well with the existing infrastructure of the Web, as shown in the following block diagram. You can read more about comet here: http://en.wikipedia.org/wiki/Comet_(programming).

Hand-rolling it all

By now you probably know where I am going with this. The techniques described previously are some of the techniques that SignalR utilizes. The techniques and standards are well known, and nothing is holding you back from working with them directly, but this is where SignalR comes in and saves the day.

Why?

The most important thing to ask in software development is "why?" (http://en.wikipedia.org/wiki/5_Whys). Why do we want all this? What is it that we're really trying to solve? We're trying to make the software more collaborative and make users work together without having artificial technical limitations to this collaboration. In fact, why not have the changes occur in real time when all the users are collaborating?

Now what?

SignalR represents an abstraction for all the techniques that it supports today, and with it we also gain the extensibility of supporting techniques that might come along in the future. It has a built-in fallback mechanism which enables it to pick the best solution for your app and its environment, and it is also based on the client connection. In addition, SignalR provides great mechanisms for scaling out in a multiserver environment, enabling applications to be blissfully unaware of the server they are running on and just work with the same abstraction as if it was only one server.

Think different

Apple coined the phrase Think different back in 1997. The phrase in itself forces you to think differently, since it is grammatically incorrect. With all the asynchronous operations and events going into a technology like SignalR, one really has to think in a different manner, but a manner that is different in a good way. It is good for users, as we are now forced to create user experiences that are non-blocking. Of course, you as a developer can force locks onto the users, but I would argue that it would be easier not to, and instead approach building the user interface in a different manner.

For instance, one of the things that we tend to build into our apps is the notion of concurrency and stale data. We don't want to run the risk of two users updating the exact same data and one client not having the updated data from the other user. Often we leave our users to get a bizarre error message that the user often won't understand. A better solution would be to have all the data on all user screens be updated as they are looking at it, and maybe even make them aware in a subtle way of the changes that happened due to the other user(s).

Personal style

Throughout this book, you'll run into things you might disagree with. It could be things in naming the classes or methods in C#, for instance, at times, I like to drop camel casing, both upper and lower, and just separate the words with underscores yielding "some_type_with_spaces". In addition, I don't use modifiers without them adding any value. You'll see that I completely avoid private as that is the default modifier for fields or properties on types. I'll also avoid things such as read-only, especially if it's a private member. Most annoyingly, you might see that I drop scoping for single line statements following an IF or FOR. Don't worry, this is my personal style; you can do as you please. All I'm asking is that you don't judge me by how my code looks. I'm not a huge fan of measuring code quality with tools such as R# and its default setting for squiggles. In fact, a colleague and I have been toying with the idea of using the underscore trick for all our code, as it really makes it a lot easier to read.

You'll notice throughout that I'm using built-in functions in the browser in JavaScript, where you might expect jQuery. The reason for this is basically that I try to limit the usage of jQuery. In fact, it's a dependency I'd prefer not to have in my solutions, as it does not add anything to the way I do things. There is a bit of an educational, also quite intentional, reason for me to not use jQuery as well: we now have most of the things we need in the browser already.

What this book covers

Chapter 1, The Primer, explains that in order to get started with SignalR and real-time web applications, it is important to understand the motivation behind wanting to have such a technology and way of approaching application development.

Chapter 2, Persistent Connections, explains that at the core of SignalR sits something called PersistentConnection, and this is where everything starts. In this chapter, you will learn how to get started with it on the backend and consume it in the frontend.

Chapter 3, Hubs, enables us to move from persistent connections to one abstraction up: something called hubs. A hub provides a more natural abstraction for most scenarios. They are easier to write and easier to consume.

Chapter 4, Groups, explains that sometimes you want to filter messages so that you have better control over which client gets which messages. Grouping in SignalR is a way to accomplish this. You will learn how to deal with this on the server and the client.

Chapter 5, State, explains that in addition to sending messages between clients and servers that are very explicit, you sometimes need to have accompanying metadata or additional data that is cross-cutting. In this chapter, you will learn about states that can go back and forth with messages.

Chapter 6, Security, explains that just about any application needs to take security into consideration. In this chapter, you will learn techniques you can apply to your SignalR code to secure messages.

Chapter 7, Scaling Out, explains that building applications that scale on multiple servers can be a bit of a puzzle. This chapter will show you how to scale out and be able to deal with these, both in an on-premise environment and in Microsoft's Windows Azure cloud.

Chapter 8, Building a WPF .NET Client, explains that SignalR is not only for web applications. It can be utilized with great success in other client types as well. This chapter shows you how to build a desktop client for Windows using WPF and .NET.

Chapter 9, Write Once, Deploy Many, takes SignalR even further, beyond both the Web and desktop to the mobile space. In this chapter, you will learn how to take your SignalR knowledge and expand into areas like iOS, Android, and Windows Phone.

Chapter 10, Monitoring, explains that debugging is a part of everyday life as a developer, and this, of course, applies to development with SignalR too. This chapter will show you how to monitor messages and look at possible performance bottlenecks.

Chapter 11, Hosting a Server Using Self-hosted OWIN, explains that open web interfaces for .NET are an abstraction enabling web frameworks to be agnostic about the underlying platform. In this chapter, we will look at how to self-host in a simple console application using OWIN.

What you need for this book

The book uses C# and JavaScript in the samples, and we will use Visual Studio 2013 as the IDE of choice. You will also be able to use Visual Studio 2013 Community edition, which is the free edition. You will need to have NuGet installed, which can be accessed at http://www.nuget.org. For the Xamarin part of this book, you will need to have access to a Mac with XCode installed, plus Xamarin Studio, which you can download at http://www.xamarin.com. Xamarin does provide a plugin for Visual Studio, but it needs to work in conjunction with a tool running on Mac OS X that compiles the code for use on iOS and also runs it either on iOS Simulator or a real device.

Who this book is for

This book is written for developers with experience in C# and JavaScript. At this stage, the developer should also have a basic knowledge of how SignalR works, as well as what the developer needs to rethink when designing applications that have a persistent connection to the server.

Some of the things that we will be discussing in the book are architectural in nature. Software architecture, patterns, and practices surround us, and this book will present some less "mainstream" ideas that are ideal for the world of small changes. You don't need to be an architect to get this; the book will keep it at an intermediate level.

Conventions

In this book, you will find a number of text styles that distinguish between different kinds of information. Here are some examples of these styles and an explanation of their meaning.

Code words in text, database table names, folder names, filenames, file extensions, path names, dummy URLs, user input, and Twitter handles are shown as follows: "At the core level of SignalR sits something called a PersistentConnection class; hubs build on top of this."

A block of code is set as follows:

function someFunctionDoingSomething() {
  // It should perform some work
}

Any command-line input or output is written as follows:

install-package <package-name> -version <package-version>

New terms and important words are shown in bold. Words that you see on the screen, for example, in menus or dialog boxes, appear in the text like this: "With the code running, you should now see a Started message in the console of the developer tool."

Note

Warnings or important notes appear in a box like this.

Tip

Tips and tricks appear like this.

Reader feedback

Feedback from our readers is always welcome. Let us know what you think about this book—what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of.

To send us general feedback, simply e-mail , and mention the book's title in the subject of your message.

If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.

Customer support

Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.

Downloading the example code

You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

Errata

Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books—maybe a mistake in the text or the code—we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title.

To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.

Piracy

Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.

Please contact us at with a link to the suspected pirated material.

We appreciate your help in protecting our authors and our ability to bring you valuable content.

Questions

If you have a problem with any aspect of this book, you can contact us at , and we will do our best to address the problem.