{"id":12035,"date":"2018-02-27T13:57:11","date_gmt":"2018-02-27T21:57:11","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/webdev\/?p=12035"},"modified":"2018-02-27T13:57:11","modified_gmt":"2018-02-27T21:57:11","slug":"asp-net-core-2-1-0-preview1-getting-started-with-signalr","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/asp-net-core-2-1-0-preview1-getting-started-with-signalr\/","title":{"rendered":"ASP.NET Core 2.1.0-preview1: Getting started with SignalR"},"content":{"rendered":"<p>Since 2013, ASP.NET developers have been using SignalR to build real-time web applications. Now, with ASP.NET Core 2.1 Preview 1, we&#8217;re bringing SignalR over to ASP.NET Core so you can build real-time web applications with all the benefits of ASP.NET Core. We released an alpha version of this new SignalR <a href=\"https:\/\/blogs.msdn.microsoft.com\/webdev\/2017\/10\/09\/announcing-signalr-for-asp-net-core-alpha-2\/\">back in October<\/a> that worked with ASP.NET Core 2.0, but now it&#8217;s ready for a broader preview and built-in to ASP.NET Core 2.1 (no additional NuGet packages required!). This new version of SignalR gave us a chance to significantly redesign some elements and learn from the lessons of the past, but the core APIs you work with should be very similar. The new design gives us a much more flexible platform on which to build the future of real-time .NET server applications. For now, though, let&#8217;s walk through a simple Chat demo to see how it works in ASP.NET Core SignalR.<\/p>\n<h2 id=\"prerequisites\">Prerequisites<\/h2>\n<p>In order to complete this tutorial you need the following tools:<\/p>\n<ol>\n<li>.NET Core SDK version <code>2.1.300-preview1<\/code> or higher.<\/li>\n<li>Node JS (just needed for NPM, to download the SignalR JavaScript library; we strongly recommend using at least version 8.9.4 of Node).<\/li>\n<li>Your IDE\/Editor of choice.<\/li>\n<\/ol>\n<h2 id=\"building-the-ui\">Building the UI<\/h2>\n<p>Let&#8217;s start by building a simple UI for a simple chat app. First, create a new Razor pages application using <code>dotnet new<\/code>: <\/p>\n<p>Add a new page for the chat UI: <\/p>\n<p>You should now have <code>Pages\/Chat.cshtml<\/code> and <code>Pages\/Chat.cshtml.cs<\/code> files in your project. First, open <code>Pages\/Chat.cshtml.cs<\/code>, change the namespace name to match your other page models and add the <code>Authorize<\/code> attribute to ensure only authenticated users can access the Chat page. <\/p>\n<p>Next, open <code>Pages\/Chat.cshtml<\/code> and add some UI: <\/p>\n<p>The UI we&#8217;ve added is fairly simple. We&#8217;re going to use <a href=\"https:\/\/docs.microsoft.com\/en-us\/aspnet\/core\/security\/authentication\/identity?tabs=visual-studio%2Caspnetcore2x\">ASP.NET Core Identity<\/a> for authentication, which means the user will be authenticated, and will have a username when we get here. To try it out, use <code>dotnet run<\/code> to launch the site and Register as a new user. Then navigate to the <code>\/Chat<\/code> endpoint, you should see the following UI:\n <a href=\"http:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/02\/chat-ui.png\"> <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/02\/chat-ui-300x247-1.png\" alt=\"The Chat UI\" width=\"300\" height=\"247\" class=\"alignnone size-medium wp-image-12045\" \/> <\/a><\/p>\n<h2 id=\"writing-the-server-code\">Writing the server code<\/h2>\n<p>In SignalR, you put server-side code in a &#8220;Hub&#8221;. Hubs contain methods that the SignalR Client allows you to invoke from the browser, much like how an MVC controller has actions that are invoked by issuing HTTP requests. However, unlike an MVC Controller Action, SignalR allows the <strong>server<\/strong> to invoke methods on the <strong>client<\/strong> as well, allowing you to develop real-time applications that notify users of new content. So, first, we need to build a hub. Back in the root of the project, create a <code>Hubs<\/code> directory and add a new file to that directory called <code>ChatHub.cs<\/code>: <\/p>\n<p>Let&#8217;s go back over that code a little bit and look at what it does.<\/p>\n<p>First, we have a class inheriting from <code>Hub<\/code>, which is the base class required for all SignalR Hubs. We apply the <code>[Authorize]<\/code> attribute to it which restricts access to the Hub to registered users and ensures that <code>Context.User<\/code> is available for us in the Hub methods. Inside Hub methods, you can use the <code>Clients<\/code> property to access the clients connected to the hub. We use the <code>.All<\/code> property, which gives us an object that can be used to send messages to every client connected to the Hub.<\/p>\n<p>When a new client connects, the <code>OnConnectedAsync<\/code> method will be invoked. We override that method to Send the <code>SendAction<\/code> message to every client, and provide two arguments: The name of the user, and the action that occurred (in this case, that they &#8220;joined&#8221; the chat session). We do the same for <code>OnDisconnectedAsync<\/code>, which is invoked when a client disconnects.<\/p>\n<p>When a client invokes the <code>Send<\/code> method, we send the <code>SendMessage<\/code> message to every client, again providing two arguments: The name of the user sending the message and the message itself. Every client will receive this message, including the sending client itself.<\/p>\n<p>To finish off the server-side, we need to add SignalR to our application. We do that in the <code>Startup.cs<\/code> file. First, add the following to the end of the <code>ConfigureServices<\/code> method to register the necessary SignalR services into the DI container: <\/p>\n<p>Then, we need to put SignalR into the middleware pipeline, and give our <code>ChatHub<\/code> hub a URL that the client can reference. We do that by adding these lines to the end of the <code>Configure<\/code> method: <\/p>\n<p>This configures the hub so that it is available at the URL <code>\/hubs\/chat<\/code>. You can use any URL you want, but it can&#8217;t match an existing MVC action or Razor Page. <strong>NOTE<\/strong>: You&#8217;ll need to add a using directive for <code>SignalRTutorial.Hubs<\/code> in order to use <code>ChatHub<\/code> in your <code>MapHub<\/code> call.<\/p>\n<h2 id=\"building-the-client-side\">Building the client-side<\/h2>\n<p>Now that we have the server hub up and running, we need to add code to the <code>Chat.cshtml<\/code> page to use the client. First, however, we need to get the SignalR JavaScript client and add it to our application. There are many ways you can do this, such as using a bundling tool like Webpack, but here we&#8217;re going to go with a fairly simple approach of copying and pasting. First, install the SignalR client using NPM: <\/p>\n<p>You can find the version of the client designed for use in Browsers in <code>node_modules\/@aspnet\/signalr\/dist\/browser<\/code>. There are minified files there as well. For now, let&#8217;s just copy the <code>signalr.js<\/code> file out of that directory and into <code>wwwroot\/lib\/signalr<\/code> in the project: <a href=\"http:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/02\/signalr-js-file.png\"> <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2018\/02\/signalr-js-file-300x287-1.png\" alt=\"SignalR JS file in the lib\/wwwroot\/signalr folder\" width=\"300\" height=\"287\" class=\"alignnone size-medium wp-image-12055\" \/> <\/a><\/p>\n<p>Now, we can add JavaScript to our <code>Chat.cshtml<\/code> page to wire everything up. At the end of the file (after the closing <code>&lt;\/ul&gt;<\/code> tag), add the following: <\/p>\n<p>We put our scripts in the <code>Scripts<\/code> Razor section, in order to ensure they end up at the very bottom of the Layout page. First, we load the <code>signalr.js<\/code> library we just copied in: <\/p>\n<p>Then, we add a script block for our own code. In that code, we first get references to some DOM elements, and define a helper function to add a new item to the <code>messages-list<\/code> list. Then, we create a new connection, connecting to the URL we specified back in the <code>Configure<\/code> method. <\/p>\n<p>At this point, the connection has not yet been opened. We need to call <code>connection.start()<\/code> to open the connection. However, before we do that we have some set-up to do. First, let&#8217;s wire up the &#8220;submit&#8221; handler for the <code>&lt;form&gt;<\/code>. When the &#8220;Send&#8221; button is pressed, this handler will be fired and we want to grab the content of the message text box and send the <code>Send<\/code> message to the server, passing the message as an argument (we also clear the text box so that the user can enter a new message): <\/p>\n<p>Then, we wire up handlers for the <code>SendMessage<\/code> and <code>SendAction<\/code> messages (remember back in the Hub we use the <code>SendAsync<\/code> method to send those messages, so we need a handler on the client for them): <\/p>\n<p>Finally, we start the connection. The <code>.start<\/code> method returns a JavaScript <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Promise\">Promise<\/a> object that completes when the connection has been established. Once it&#8217;s established, we want to enable the text box and button: <\/p>\n<h2 id=\"testing-it-out\">Testing it out<\/h2>\n<p>With all that code in place, it should be ready to go. Use <code>dotnet run<\/code> to launch the app and give it a try! Then, use a Private Browsing window and log in as a different user. You should be able to chat back and forth between the browser windows.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>This has been a brief overview of how to get started with SignalR in ASP.NET Core 2.1 Preview 1. Check out the<\/p>\n<p><a href=\"https:\/\/github.com\/anurse\/SignalRTutorial\/tree\/2a3debb01dc79f3bb68048511f53d74b6105e78a\">full code for this tutorial<\/a> if you&#8217;d like to see more details. If you need help, post questions on <a href=\"https:\/\/stackoverflow.com\">StackOverflow<\/a> using the <a href=\"https:\/\/stackoverflow.com\/questions\/tagged\/signalr-core\"><code>signalr-core<\/code><\/a> tag. Finally, if you think you&#8217;ve found a bug, file it on our <a href=\"https:\/\/github.com\/aspnet\/SignalR\">GitHub repository<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Since 2013, ASP.NET developers have been using SignalR to build real-time web applications. Now, with ASP.NET Core 2.1 Preview 1, we&#8217;re bringing SignalR over to ASP.NET Core so you can build real-time web applications with all the benefits of ASP.NET Core. We released an alpha version of this new SignalR back in October that worked [&hellip;]<\/p>\n","protected":false},"author":701,"featured_media":21397,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[197,7509,7256],"tags":[7542,7408],"class_list":["post-12035","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aspnet","category-aspnetcore","category-signalr","tag-asp-net-core-2-1-0-preview1","tag-signalr"],"acf":[],"blog_post_summary":"<p>Since 2013, ASP.NET developers have been using SignalR to build real-time web applications. Now, with ASP.NET Core 2.1 Preview 1, we&#8217;re bringing SignalR over to ASP.NET Core so you can build real-time web applications with all the benefits of ASP.NET Core. We released an alpha version of this new SignalR back in October that worked [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/12035","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/701"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=12035"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/12035\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/21397"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=12035"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=12035"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=12035"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}