{"id":28451,"date":"2019-07-09T00:00:00","date_gmt":"2019-07-08T22:00:00","guid":{"rendered":"https:\/\/blexin.com\/applicazioni-real-time-con-signalr-asp-net-core-e-angular\/"},"modified":"2021-05-20T18:56:39","modified_gmt":"2021-05-20T16:56:39","slug":"real-time-applications-with-signalr-asp-net-core-and-angular","status":"publish","type":"post","link":"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/","title":{"rendered":"Real-time applications with SignalR, ASP.NET Core and Angular"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"608\" data-attachment-id=\"28442\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/attachment\/8db2df13-524e-4494-b65a-7caa972acced-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?fit=1024%2C608&amp;ssl=1\" data-orig-size=\"1024,608\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"8db2df13-524e-4494-b65a-7caa972acced\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?fit=300%2C178&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?fit=1024%2C608&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?resize=1024%2C608&#038;ssl=1\" alt=\"\" class=\"wp-image-28442\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced-980x582.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced-480x285.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose we want to create a monitoring web application, that provides users with a dashboard able to display a range of information, which are updated over time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A first approach is to periodically call an API at defined time intervals (<em>polling<\/em>) to update data on the dashboard. There\u2019s a problem, anyway: if there are no updated data, we are unnecessarily increasing the network traffic with our requests. An alternative can be the&nbsp;<em>long-polling<\/em>&nbsp;technique: if the server has no available data, it can keep the request alive until something happens, or the preset timeout is reached, rather than send an empty response. If new data are present, the complete response reaches the client. A completely different approach is to reverse roles: the backend contacts the clients, when new data are available (push).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Remember that HTML 5 has standardized WebSocket, a permanent bidirectional connection, that can be configured with a Javascript interface in compatible browsers. Unfortunately, there must be complete support to WebSocket, both on client and server side, to make it available. We need then to provide for alternative systems (<em>fallback<\/em>), that allows our application to run, no matter what.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Microsoft has published in 2013 an open-source library called&nbsp;<strong>SignalR<\/strong>&nbsp;for&nbsp;<strong>ASP.NET<\/strong>, which has been rewritten&nbsp;in 2018 for ASP.NET Core. SignalR abstracts from all details related to communication mechanisms, and it chooses the best one among those available. The result is the possibility to write the code, as if we are always in&nbsp;<em>push-mode<\/em>. With SignalR the server can call a JavaScript method on all its connected clients, or on a specific one.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We create an ASP.NET Core project with a web-api template, deleting the sample controller, that has been produced. With NuGet, we add&nbsp;<em>Microsoft.AspNet.SignalR<\/em>&nbsp;to the project, in order to create a&nbsp;<strong>Hub<\/strong>. The hub is the high-level pipeline able to call the client code, sending messages containing name and parameters of the requested method. Objects sent as parameters will be de-serialized using the appropriate protocol. The client searches in the page code a method corresponding to the name and, if it finds it, it invokes it passing de-serialized data as parameters.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nusing Microsoft.AspNetCore.SignalR;\n\u00a0\nnamespace SignalR.Hubs\n{\n\u00a0\u00a0\u00a0\u00a0public class NotificationHub : Hub { }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">As you probably know, in ASP.NET Core the management pipeline of a HTTP request can be configured adding some&nbsp;<strong>middleware<\/strong>, that intercepts a request, adds a configured functionality and let it proceed to the next middleware. The SignalR middleware must be configured in advance, adding in the method&nbsp;<em>ConfigureServices<\/em>&nbsp;of the&nbsp;<strong>Startup<\/strong>&nbsp;class the extension method&nbsp;<em>services.AddSignalR()<\/em>. Now we can add the middleware to the pipeline, using the extension method app.UseSignalR() in the&nbsp;<em>Configure<\/em>&nbsp;method of the Startup class. During this operation, we can pass configuration parameters, including the route of our hub:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\napp.UseSignalR(route =&gt;\n{\n\u00a0\u00a0\u00a0\u00a0route.MapHub&lt;notificationhub&gt;(&quot;\/notificationHub&quot;);\n})\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">An interesting scenario, that allows us to look at another interesting feature in ASP.NET Core, is the&nbsp;<em>hosting<\/em>&nbsp;of a SignalR Hub in a&nbsp;<strong>background worker<\/strong>&nbsp;process context.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine we want to implement the following use case:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>run business logic<\/li><li>wait some time<\/li><li>decide if stop or repeat the process.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">In ASP.NET Core, we can use the interface&nbsp;<em>IHostedService<\/em>&nbsp;provided by the framework, to implement the execution of processes in background in a .NET Core application. Methods to be implemented are&nbsp;<em>StartAsync()<\/em>&nbsp;and&nbsp;<em>StopAsync()<\/em>. Very simply: StartAsync is invoked to the host startup, while StopAsync is invoked to the host shutdown.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We add then a class&nbsp;<em>DashboardHostedService<\/em>&nbsp;to the project, that implements&nbsp;<em>IHostedService<\/em>. We add in the method&nbsp;<em>ConfigureServices<\/em>&nbsp;of the Startup class the interface registration:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nservices.AddHostedService&lt;dashboardhostedservice&gt;();\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">In the class constructor&nbsp;<em>DashboardHostedService,<\/em>&nbsp;we inject&nbsp;<em>IHubContext<\/em>&nbsp;to access to the hub added to our application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the method StartAsync we set then a timer, that will run the code contained in the method DoWork() every two seconds. This method sends a message with four strings casually generated.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But to whom does it transmit them? In our example, we are sending the message to all connected clients. However, SignalR offers the opportunity to send messages to single users or to users\u2019 groups. In this&nbsp;<a href=\"https:\/\/docs.microsoft.com\/en-us\/aspnet\/core\/signalr\/groups?view=aspnetcore-2.2\" target=\"_blank\" rel=\"noreferrer noopener\">article<\/a>, you find details that involve authentication and authorization functionalities in ASP.NET Core. It is interesting to note,&nbsp;that a user could be connected both on desktop and on mobile. Every device would have a separate SignalR connection, but both of them would be associated with&nbsp;the same user.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nusing Microsoft.AspNetCore.SignalR;\nusing Microsoft.Extensions.Hosting;\nusing SignalR.Hubs;\nusing System;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\n\u00a0\nnamespace SignalR\n{\n\u00a0\u00a0\u00a0\u00a0public class DashboardHostedService: IHostedService\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0private Timer _timer;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0private readonly IHubContext&lt;notificationhub&gt; _hubContext;\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0public DashboardHostedService(IHubContext&lt;notificationhub&gt; hubContext)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0_hubContext = hubContext;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0public Task StartAsync(CancellationToken cancellationToken)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0_timer = new Timer(DoWork, null, TimeSpan.Zero,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0TimeSpan.FromSeconds(2));\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return Task.CompletedTask;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0private void DoWork(object state)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0_hubContext.Clients.All.SendAsync(&quot;SendMessage&quot;, \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0val1 = getRandomString(),\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0val2 = getRandomString(),\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0val3 = getRandomString(),\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0val4 = getRandomString()\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0public Task StopAsync(CancellationToken cancellationToken)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0_timer?.Change(Timeout.Infinite, 0);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return Task.CompletedTask;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s see how to manage the client part. We create, for example, an Angular application with the command&nbsp;<em>ng new SignalR<\/em>&nbsp;of the Angular CLI. We install then the package node for SignalR (<em>npm i @aspnet\/signalr<\/em>). We add then a service, which allows us to connect to the hub previously created and to receive messages.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here a first possible approach, based on the return by the service of an Observable&lt;Message&gt; in the method getMessage(), by the use of a privately declared Subject&lt;Message&gt; (Message is a typescript interface corresponding to the object returned from the backend):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n@Injectable({\n\u00a0providedIn: &#039;root&#039;\n})\nexport class SignalRService {\n\u00a0private message$: Subject&lt;message&gt;;\n\u00a0private connection: signalR.HubConnection;\n\u00a0\n\u00a0constructor() {\n\u00a0\u00a0\u00a0this.message$ = new Subject&lt;message&gt;();\n\u00a0\u00a0\u00a0this.connection = new signalR.HubConnectionBuilder()\n\u00a0\u00a0\u00a0.withUrl(environment.hubUrl)\n\u00a0\u00a0\u00a0.build();\n\u00a0\u00a0\u00a0this.connect();\n\u00a0}\n\u00a0private connect() {\n\u00a0\u00a0\u00a0this.connection.start().catch(err =&gt; console.log(err));\n\u00a0\u00a0\u00a0this.connection.on(&#039;SendMessage&#039;, (message) =&gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0this.message$.next(message);\n\u00a0\u00a0\u00a0});\n\u00a0}\n\u00a0public getMessage(): Observable&lt;message&gt; {\n\u00a0\u00a0\u00a0return this.message$.asObservable();\n\u00a0}\n\u00a0public disconnect() {\n\u00a0\u00a0\u00a0this.connection.stop();\n\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Inside the constructor(), we create a SignalR.HubConnection type object, that will serve to connect to the server. We pass to its our hub URL by the use of the file environment.ts:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nthis.connection = new signalR.HubConnectionBuilder()\n\u00a0\u00a0\u00a0.withUrl(environment.hubUrl)\n\u00a0\u00a0\u00a0.build();\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The constructor also looks after to invoke the connect() method, that makes the actual connection, logging possible mistakes in the console.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nthis.connection.start().catch(err =&gt; console.log(err));\nthis.connection.on(&#039;SendMessage&#039;, (message) =&gt; {\n\u00a0\u00a0this.message$.next(message);\n});\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">A component that want to show messages coming from the backend (as it inject the service in the constructor), should subscribe to the getMessage() method and manage the arrived message. In the case of AppComponent, for example:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n@Component({\n\u00a0selector: &#039;app-root&#039;,\n\u00a0templateUrl: &#039;.\/app.component.html&#039;,\n\u00a0styleUrls: &#x5B;&#039;.\/app.component.css&#039;]\n})\nexport class AppComponent implements OnDestroy {\n\u00a0private signalRSubscription: Subscription;\n\u00a0\n\u00a0public content: Message;\n\u00a0\n\u00a0constructor(private signalrService: SignalRService) {\n\u00a0\u00a0\u00a0this.signalRSubscription = this.signalrService.getMessage().subscribe(\n\u00a0\u00a0\u00a0\u00a0\u00a0(message) =&gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.content = message;\n\u00a0\u00a0\u00a0});\n\u00a0}\n\u00a0ngOnDestroy(): void {\n\u00a0\u00a0\u00a0this.signalrService.disconnect();\n\u00a0\u00a0\u00a0this.signalRSubscription.unsubscribe();\n\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Using a Subject &lt;Message&gt; allows us to manage in more components at the same time and regardless of the Message returned from the hub (both for subscribe and for unsubscribe), but we must pay attention to a careless use of the Subject. Let\u2019s consider the following getMessage() version:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic getMessage(): Observable&lt;message&gt; {\n\u00a0\u00a0\u00a0return this.message$;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Now the component is able to emit a Message it too with this simple&nbsp;code:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nconst produceMessage = this.signalrService.getMessage() as Subject&amp;lt;any&gt;;\n\u00a0produceMessage.next( {val1: &#039;a&#039;});\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This code throws an exception, if the method getMessage() returns the Subject&lt;Message&gt; asObservable!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A second approach, more simple, that we can use in event of a single component is interested in managing messages coming from the backend, is the following:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n@Injectable({\n\u00a0providedIn: &#039;root&#039;\n})\nexport class SignalrService {\n\u00a0connection: signalR.HubConnection;\n\u00a0\n\u00a0constructor() {\n\u00a0\u00a0\u00a0this.connection = new signalR.HubConnectionBuilder()\n\u00a0\u00a0\u00a0.withUrl(environment.hubAddress)\n\u00a0\u00a0\u00a0.build();\n\u00a0\u00a0\u00a0this.connect();\n\u00a0}\n\u00a0\n\u00a0public connect() {\n\u00a0\u00a0\u00a0if (this.connection.state === signalR.HubConnectionState.Disconnected) {\n\u00a0\u00a0\u00a0\u00a0\u00a0this.connection.start().catch(err =&gt; console.log(err));\n\u00a0\u00a0\u00a0}\n\u00a0}\n\u00a0\n\u00a0public getMessage(next) {\n\u00a0\u00a0\u00a0\u00a0\u00a0this.connection.on(&#039;SendMessage&#039;, (message) =&gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0next(message);\n\u00a0\u00a0\u00a0\u00a0\u00a0});\n\u00a0}\n\u00a0\n\u00a0public disconnect() {\n\u00a0\u00a0\u00a0this.connection.stop();\n\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">We can simply pass the function callback to the method getMessage, and the function takes as argument the message coming from the backend. In this case, AppComponent can become:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic content: IMessage;\nconstructor(private signalrService: SignalrService) {\n\u00a0\u00a0\u00a0this.signalrService.getMessage(\n\u00a0\u00a0\u00a0\u00a0\u00a0(message: IMessage) =&gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.content = message;\n\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0);\n}\nngOnDestroy(): void {\n\u00a0\u00a0\u00a0this.signalrService.disconnect();\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Last few code lines, respectively in&nbsp;<em>app.component.html<\/em>&nbsp;and&nbsp;<em>app.component.css<\/em>,to give some stylish, and the application is completed<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;div style=&quot;text-align:center&quot;&gt;\n\u00a0\u00a0&lt;h1&gt;\n\u00a0\u00a0\u00a0\u00a0DASHBOARD\n\u00a0\u00a0&lt;\/h1&gt;\n&lt;\/div&gt;\n&lt;div class=&quot;card-container&quot;&gt;\n\u00a0\u00a0&lt;div class=&quot;card&quot;&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;div class=&quot;container&quot;&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;h4&gt;&lt;b&gt;Valore 1&lt;\/b&gt;&lt;\/h4&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;p&gt;{{content.val1}}&lt;\/p&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0&lt;div class=&quot;card&quot;&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;div class=&quot;container&quot;&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;h4&gt;&lt;b&gt;Valore 2&lt;\/b&gt;&lt;\/h4&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;p&gt;{{content.val2}}&lt;\/p&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0&lt;div class=&quot;card&quot;&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;div class=&quot;container&quot;&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;h4&gt;&lt;b&gt;Valore 3&lt;\/b&gt;&lt;\/h4&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;p&gt;{{content.val3}}&lt;\/p&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0&lt;div class=&quot;card&quot;&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;div class=&quot;container&quot;&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;h4&gt;&lt;b&gt;Valore 4&lt;\/b&gt;&lt;\/h4&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;p&gt;{{content.val4}}&lt;\/p&gt;\n\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\n\u00a0\u00a0&lt;\/div&gt;\n&lt;\/div&gt;\n\u00a0\n.card-container {\n\u00a0\u00a0display: flex;\n\u00a0\u00a0flex-wrap: wrap;\n}\n\u00a0\n.card {\n\u00a0\u00a0box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);\n\u00a0\u00a0transition: 0.3s;\n\u00a0\u00a0width: 40%;\n\u00a0\u00a0flex-grow: 1;\n\u00a0\u00a0margin: 10px;\n}\n\u00a0\n.card:hover {\n\u00a0\u00a0box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);\n}\n\u00a0\n.container {\n\u00a0\u00a0padding: 2px 16px;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">We start the backend for first, then the frontend and check the final result:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"229\" data-attachment-id=\"28448\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/attachment\/dashboard-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/dashboard.gif?fit=600%2C229&amp;ssl=1\" data-orig-size=\"600,229\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"dashboard\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/dashboard.gif?fit=300%2C115&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/dashboard.gif?fit=600%2C229&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/dashboard.gif?resize=600%2C229&#038;ssl=1\" alt=\"\" class=\"wp-image-28448\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">It looks fine! You can find the code here:&nbsp;<a href=\"https:\/\/github.com\/AARNOLD87\/SignalRWithAngular\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/AARNOLD87\/SignalRWithAngular<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">See you next!<\/p>\n\n\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Let\u2019s see how to send information from server to client using ASP.NET Core, SignalR and Angular<\/p>\n","protected":false},"author":196716245,"featured_media":28442,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"","_et_gb_content_width":"","_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","_crdt_document":"","inline_featured_image":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false},"categories":[688637524],"tags":[688637390,688637416],"class_list":["post-28451","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-en","tag-angular-en","tag-asp-net-core-en"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Real-time applications with SignalR, ASP.NET Core and Angular - Blexin<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Real-time applications with SignalR, ASP.NET Core and Angular - Blexin\" \/>\n<meta property=\"og:description\" content=\"Let\u2019s see how to send information from server to client using ASP.NET Core, SignalR and Angular\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/\" \/>\n<meta property=\"og:site_name\" content=\"Blexin\" \/>\n<meta property=\"article:published_time\" content=\"2019-07-08T22:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-05-20T16:56:39+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i2.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?fit=1024%2C608&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"608\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Salvatore Sorrentino\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Salvatore Sorrentino\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/\"},\"author\":{\"name\":\"Salvatore Sorrentino\",\"@id\":\"https:\/\/blexin.com\/en\/#\/schema\/person\/354db2bc97cac71c2ceeca21a92d5bed\"},\"headline\":\"Real-time applications with SignalR, ASP.NET Core and Angular\",\"datePublished\":\"2019-07-08T22:00:00+00:00\",\"dateModified\":\"2021-05-20T16:56:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/\"},\"wordCount\":1157,\"image\":{\"@id\":\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?fit=1024%2C608&ssl=1\",\"keywords\":[\"Angular\",\"Asp.net core\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/\",\"url\":\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/\",\"name\":\"Real-time applications with SignalR, ASP.NET Core and Angular - Blexin\",\"isPartOf\":{\"@id\":\"https:\/\/blexin.com\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?fit=1024%2C608&ssl=1\",\"datePublished\":\"2019-07-08T22:00:00+00:00\",\"dateModified\":\"2021-05-20T16:56:39+00:00\",\"author\":{\"@id\":\"https:\/\/blexin.com\/en\/#\/schema\/person\/354db2bc97cac71c2ceeca21a92d5bed\"},\"breadcrumb\":{\"@id\":\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/#primaryimage\",\"url\":\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?fit=1024%2C608&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?fit=1024%2C608&ssl=1\",\"width\":1024,\"height\":608},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blexin.com\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Real-time applications with SignalR, ASP.NET Core and Angular\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blexin.com\/en\/#website\",\"url\":\"https:\/\/blexin.com\/en\/\",\"name\":\"Blexin\",\"description\":\"Con noi \u00e8 semplice\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blexin.com\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blexin.com\/en\/#\/schema\/person\/354db2bc97cac71c2ceeca21a92d5bed\",\"name\":\"Salvatore Sorrentino\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blexin.com\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a6ec0dc827d2acaa55df9dbf1007e23f6fcb8c9436df52ab48274bb2221085bf?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a6ec0dc827d2acaa55df9dbf1007e23f6fcb8c9436df52ab48274bb2221085bf?s=96&d=identicon&r=g\",\"caption\":\"Salvatore Sorrentino\"},\"url\":\"https:\/\/blexin.com\/en\/author\/salvatore-sorrentinoblexin-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Real-time applications with SignalR, ASP.NET Core and Angular - Blexin","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/","og_locale":"en_US","og_type":"article","og_title":"Real-time applications with SignalR, ASP.NET Core and Angular - Blexin","og_description":"Let\u2019s see how to send information from server to client using ASP.NET Core, SignalR and Angular","og_url":"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/","og_site_name":"Blexin","article_published_time":"2019-07-08T22:00:00+00:00","article_modified_time":"2021-05-20T16:56:39+00:00","og_image":[{"width":1024,"height":608,"url":"https:\/\/i2.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?fit=1024%2C608&ssl=1","type":"image\/png"}],"author":"Salvatore Sorrentino","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Salvatore Sorrentino","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/#article","isPartOf":{"@id":"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/"},"author":{"name":"Salvatore Sorrentino","@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/354db2bc97cac71c2ceeca21a92d5bed"},"headline":"Real-time applications with SignalR, ASP.NET Core and Angular","datePublished":"2019-07-08T22:00:00+00:00","dateModified":"2021-05-20T16:56:39+00:00","mainEntityOfPage":{"@id":"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/"},"wordCount":1157,"image":{"@id":"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?fit=1024%2C608&ssl=1","keywords":["Angular","Asp.net core"],"articleSection":["Blog"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/","url":"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/","name":"Real-time applications with SignalR, ASP.NET Core and Angular - Blexin","isPartOf":{"@id":"https:\/\/blexin.com\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/#primaryimage"},"image":{"@id":"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?fit=1024%2C608&ssl=1","datePublished":"2019-07-08T22:00:00+00:00","dateModified":"2021-05-20T16:56:39+00:00","author":{"@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/354db2bc97cac71c2ceeca21a92d5bed"},"breadcrumb":{"@id":"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/#primaryimage","url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?fit=1024%2C608&ssl=1","contentUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?fit=1024%2C608&ssl=1","width":1024,"height":608},{"@type":"BreadcrumbList","@id":"https:\/\/blexin.com\/en\/blog-en\/real-time-applications-with-signalr-asp-net-core-and-angular\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blexin.com\/en\/"},{"@type":"ListItem","position":2,"name":"Real-time applications with SignalR, ASP.NET Core and Angular"}]},{"@type":"WebSite","@id":"https:\/\/blexin.com\/en\/#website","url":"https:\/\/blexin.com\/en\/","name":"Blexin","description":"Con noi \u00e8 semplice","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blexin.com\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/354db2bc97cac71c2ceeca21a92d5bed","name":"Salvatore Sorrentino","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/a6ec0dc827d2acaa55df9dbf1007e23f6fcb8c9436df52ab48274bb2221085bf?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a6ec0dc827d2acaa55df9dbf1007e23f6fcb8c9436df52ab48274bb2221085bf?s=96&d=identicon&r=g","caption":"Salvatore Sorrentino"},"url":"https:\/\/blexin.com\/en\/author\/salvatore-sorrentinoblexin-com\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8db2df13-524e-4494-b65a-7caa972acced.png?fit=1024%2C608&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/pcyUBx-7oT","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/28451","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/users\/196716245"}],"replies":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/comments?post=28451"}],"version-history":[{"count":4,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/28451\/revisions"}],"predecessor-version":[{"id":31978,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/28451\/revisions\/31978"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/media\/28442"}],"wp:attachment":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/media?parent=28451"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/categories?post=28451"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/tags?post=28451"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}