{"id":116,"date":"2026-06-29T10:38:26","date_gmt":"2026-06-29T10:38:26","guid":{"rendered":"https:\/\/blog.vigplanet.com\/?p=116"},"modified":"2026-06-29T10:41:01","modified_gmt":"2026-06-29T10:41:01","slug":"building-a-real-time-agent-server-communication-system-using-signalr-in-asp-net-core","status":"publish","type":"post","link":"https:\/\/blog.vigplanet.com\/?p=116","title":{"rendered":"Building a Real-Time Agent\u2013Server Communication System Using SignalR in ASP.NET Core"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">In modern applications, real-time communication is no longer optional. Whether it\u2019s remote agents, background services, live dashboards, or command execution systems \u2014 instant two-way communication is critical.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this article, we\u2019ll build a Real-Time Agent\u2013Server Architecture using SignalR in ASP.NET Core, understand why SignalR beats REST, and walk through a live working C# demo.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Is Agent\u2013Server Architecture?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">An Agent\u2013Server architecture consists of:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83e\udde0 Server (Central Controller)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sends commands<\/li>\n\n\n\n<li>Manages connected agents<\/li>\n\n\n\n<li>Collects responses in real time<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83e\udd16 Agent (Client \/ Worker)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Runs on user machines or servers<\/li>\n\n\n\n<li>Listens for instructions<\/li>\n\n\n\n<li>Executes tasks<\/li>\n\n\n\n<li>Sends results back instantly<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Real-world Use Cases<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Remote system monitoring<\/li>\n\n\n\n<li>IoT device control<\/li>\n\n\n\n<li>Automated SQL execution<\/li>\n\n\n\n<li>Real-time admin dashboards<\/li>\n\n\n\n<li>Background Windows services<\/li>\n\n\n\n<li>DevOps automation agents<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Why SignalR Over REST APIs?<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th class=\"has-text-align-left\" data-align=\"left\">Feature<\/th><th class=\"has-text-align-left\" data-align=\"left\">REST API<\/th><th class=\"has-text-align-left\" data-align=\"left\">SignalR<\/th><\/tr><tr><td>Communication<\/td><td>Request\u2013Response<\/td><td>Bi-directional<\/td><\/tr><tr><td>Real-time<\/td><td>\u274c No<\/td><td>\u2705 Yes<\/td><\/tr><tr><td>Server \u2192 Client Push<\/td><td>\u274c No<\/td><td>\u2705 Yes<\/td><\/tr><tr><td>Connection State<\/td><td>Stateless<\/td><td>Persistent<\/td><\/tr><tr><td>Latency<\/td><td>High<\/td><td>Very Low<\/td><\/tr><tr><td>Agent Control<\/td><td>Poor<\/td><td>Excellent<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">REST is pull-based. SignalR is push-based.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the server must command agents instantly, REST simply isn\u2019t enough.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Is SignalR?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">SignalR is a real-time communication framework built by Microsoft for ASP.NET.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It enables:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Persistent connections<\/li>\n\n\n\n<li>Automatic reconnection<\/li>\n\n\n\n<li>JSON serialization<\/li>\n\n\n\n<li>WebSockets (with fallback)<\/li>\n\n\n\n<li>Strongly-typed hub methods<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Perfect for live agent execution systems.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Real-Time Execution &amp; Response Flow<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd04 Execution Lifecycle<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Agent starts and connects to SignalR Hub<\/li>\n\n\n\n<li>Server detects connected agent<\/li>\n\n\n\n<li>Server sends command (SQL \/ job \/ task)<\/li>\n\n\n\n<li>Agent executes the task<\/li>\n\n\n\n<li>Agent sends JSON response<\/li>\n\n\n\n<li>Server processes or broadcasts result<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83d\udca1&nbsp;<strong>No polling. No delays. No refresh.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Architecture Overview<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510        SignalR        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502   Server     \u2502  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25b6  \u2502    Agent     \u2502\n\u2502 ASP.NET Core \u2502  \u25c0\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  \u2502  Console App \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518   Real-Time JSON      \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">1: Create SignalR Hub (Server)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udcc1 AgentHub.cs<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>using Microsoft.AspNetCore.SignalR;\n\npublic class AgentHub : Hub\n{\n    public async Task SendCommand(string agentId, string command)\n    {\n        await Clients.User(agentId)\n                     .SendAsync(\"ExecuteCommand\", command);\n    }\n\n    public async Task ReceiveResult(string agentId, string result)\n    {\n        Console.WriteLine($\"Agent {agentId}: {result}\");\n    }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Register SignalR in ASP.NET Core<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udcc1 Program.cs<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>builder.Services.AddSignalR();\n\napp.MapHub&lt;AgentHub&gt;(\"\/hubs\/agent\");<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Agent Console Application (C#)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This agent connects to the server and&nbsp;<strong>executes commands live<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udcc1 Program.cs (Agent)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>using Microsoft.AspNetCore.SignalR.Client;\n\nclass Program\n{\n    static async Task Main(string&#91;] args)\n    {\n        var agentId = \"agent1\";\n\n        var connection = new HubConnectionBuilder()\n            .WithUrl(\"http:\/\/localhost:5000\/hubs\/agent\")\n            .WithAutomaticReconnect()\n            .Build();\n\n        connection.On&lt;string&gt;(\"ExecuteCommand\", async (command) =&gt;\n        {\n            Console.WriteLine($\"Received: {command}\");\n\n            string result = $\"Executed command: {command} at {DateTime.Now}\";\n\n            await connection.SendAsync(\n                \"ReceiveResult\",\n                agentId,\n                result\n            );\n        });\n\n        await connection.StartAsync();\n        Console.WriteLine(\"Agent connected.\");\n\n        Console.ReadLine();\n    }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Send Command From Server<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>await hubContext.Clients\n    .User(\"agent1\")\n    .SendAsync(\"ExecuteCommand\", \"SELECT * FROM Users\");<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u2714 Agent receives instantly<br>\u2714 Executes logic<br>\u2714 Sends response live<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why This System Is Powerful<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u2705 True real-time execution<br>\u2705 Scales to thousands of agents<br>\u2705 No polling or cron jobs<br>\u2705 Works with Windows Services<br>\u2705 Secure (JWT \/ headers supported)<br>\u2705 Cloud &amp; on-prem friendly<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Advanced Enhancements (Next Level)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ud83d\udd10 JWT authentication per agent<\/li>\n\n\n\n<li>\ud83d\udcca Live dashboard (React \/ Blazor)<\/li>\n\n\n\n<li>\ud83d\uddc2 Command queue &amp; history<\/li>\n\n\n\n<li>\ud83e\udde0 AI-driven task routing<\/li>\n\n\n\n<li>\ud83e\udde9 Plugin-based agent modules<\/li>\n\n\n\n<li>\u2601 Dockerized agents<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Final Thoughts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you\u2019re building:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Agent-based systems<\/li>\n\n\n\n<li>Remote execution tools<\/li>\n\n\n\n<li>Live monitoring apps<\/li>\n\n\n\n<li>Admin dashboards<\/li>\n\n\n\n<li>Real-time automation<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83d\udc49 SignalR is the right foundation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It transforms your app from request-based to event-driven, unlocking true real-time power.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">People also reading<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Securing SignalR: JWT Authentication for Agent-Server Communication<\/li>\n\n\n\n<li>Building a Real-Time Dashboard with Blazor and SignalR<\/li>\n\n\n\n<li>Implementing Command Queuing and History in SignalR Agent Systems<\/li>\n\n\n\n<li>Scaling SignalR: Handling Thousands of Concurrent Agent Connections<\/li>\n\n\n\n<li>Agent-Based Systems with Docker and SignalR in ASP.NET Core<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In modern applications, real-time communication is no longer optional. Whether it\u2019s remote agents, background services, live dashboards, or command execution systems \u2014 instant two-way communication is critical. In this article, we\u2019ll build a Real-Time Agent\u2013Server Architecture using SignalR in ASP.NET Core, understand why SignalR beats REST, and walk through a live working C# demo. What<\/p>\n","protected":false},"author":1,"featured_media":118,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-116","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blog.vigplanet.com\/index.php?rest_route=\/wp\/v2\/posts\/116","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.vigplanet.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.vigplanet.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.vigplanet.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.vigplanet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=116"}],"version-history":[{"count":1,"href":"https:\/\/blog.vigplanet.com\/index.php?rest_route=\/wp\/v2\/posts\/116\/revisions"}],"predecessor-version":[{"id":117,"href":"https:\/\/blog.vigplanet.com\/index.php?rest_route=\/wp\/v2\/posts\/116\/revisions\/117"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.vigplanet.com\/index.php?rest_route=\/wp\/v2\/media\/118"}],"wp:attachment":[{"href":"https:\/\/blog.vigplanet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=116"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.vigplanet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=116"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.vigplanet.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=116"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}