如何使用SignalR与特定客户进行通信?

时间:2016-07-09 03:58:52

标签: c# asp.net-mvc signalr

我是SignalR的新手。我需要与特定客户沟通

这是我到目前为止所做的事情

EmployeeHub.cs

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;

namespace WebApplication1
{
    public class EmployeeHub : Hub
    {
        [HubMethodName("NotifyClients")]
        public static void NotifyCurrentEmployeeInformationToAllClients(string connectionID)
        {
            IHubContext context = GlobalHost.ConnectionManager.GetHubContext<EmployeeHub>();

            // update the specific connected client         
             context.Clients.Client(connectionID).updatedClients();
        }
    }
}

HomeController.cs

using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web.Mvc;
using WebApplication1.Models;

namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        List<Employee> empList;

        //Fetch Employee Records
        public ActionResult Index()
        {
            return View();
        }
        [HttpGet]
        public ActionResult GetAllEmployeeRecords()
        {
            using (var context = new EmployeeContext())
            {
                empList = context
                .Employees
                .ToList();
            }          
            return PartialView("_EmployeeList", empList);
        }


        //Insert Employee Record
        public ActionResult Insert()
        {
            return View();
        }
        [HttpPost]        
        public ActionResult Insert(DataPacket dataPacket)
        {
            if (ModelState.IsValid)
            {
                //Insert into Employee table 
                using (var context = new EmployeeContext())
                {
                    context.Employees.Add(dataPacket.Employee);
                    context.SaveChanges();
                }
            }

            //Once the record is inserted , then notify(Clients)
            EmployeeHub.NotifyCurrentEmployeeInformationToAllClients(dataPacket.ConnectionID);
            return RedirectToAction("Index");
        }       
}

DataPacket.cs

public class Employee
    {
        [Key]
        public int EmployeeID { get; set; }
        public string EmployeeName { get; set; }
        public string EmailAdress { get; set; }
        public string MobileNumber { get; set; }      
    }

    public class DataPacket
    {
        public Employee Employee { get; set; }
        public string ConnectionID { get; set; }
    }

最后是 Index.cshtml

@model IList<WebApplication1.Models.Employee>
@{
    ViewBag.Title = "Index";
}
<link href="~/Content/bootstrap/css/bootstrap.min.css" rel="stylesheet" />

<div>    
        <h1 style="color: green">CRUD using SignalR,MVC and Entity Framework</h1>
        <table border="1">            
            ................................
        ................................
        </table>
    <br /><br />       
        <div id="dataTable"></div>
    </div>

@section JavaScript{
    <script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
    <script src="/signalr/hubs"></script>
    <script type="text/javascript">

        $(function () {
            // Create a proxy to signalr hub on web server. It reference the hub.
            var notificationFromHub = $.connection.employeeHub;

            // Connect to signalr hub
            $.connection.hub.start().done(function () {
                FetchEmployees();
            });

            // Notify to client with the recent updates
            notificationFromHub.client.updatedClients = function () {
                FetchEmployees();
            };
        });

        function FetchEmployees() {
            var model = $('#dataTable');
            $.ajax({
                url: '/home/GetAllEmployeeRecords',
                contentType: 'application/html ; charset:utf-8',
                type: 'GET',
                dataType: 'html'
            })
                .success(function (result) { model.empty().append(result); })               
        }

        // Insert Employee Record
        function InsertEmployee()
        {


                    var employee = {
                        EmployeeID: $('#txtEmployeeId').val(),
                        EmployeeName: $('#txtEmployeeName').val(),
                        EmailAdress: $('#txtEmail').val(),
                        MobileNumber: $('#txtMobile').val(),                      
                    };

                    var dataPacket = {
                        Employee: employee,
                        ConnectionID: GenerateRandomNumbers()
                    }

                    $.ajax({
                    url: '/home/Insert',
                    type: 'POST',
                    data: JSON.stringify(dataPacket),
                    contentType: "application/json;charset=utf-8",
                    success: function (data) {
                        alert('Employee added Successfully');                       
                    },
                    error: function () {
                        alert('Employee not Added');
                    }
                });
        }        

        //Generate RandomNumbers
        function GenerateRandomNumbers() {
            var min = 1;
            var max = 10;
            return Math.floor(Math.random() * (max - min + 1) + min);
        }
    </script>
}

我目前使用随机数生成用于测试目的的客户端ID。问题是,记录被添加到数据库中,但是在页面加载之前,没有发生从SignalR到客户端的通知。

E.g。当我点击“添加新员工”按钮时就是这种情况。

enter image description here

当我执行页面刷新时,只有数据会反映在表格中

enter image description here

我也提到了this SO Q/A,但我认为我错过了一些东西。

我错过了什么?

1 个答案:

答案 0 :(得分:1)

在SignalR中,ConnectionId是特定连接客户端的特定号码。因此,您的ConnectionID: GenerateRandomNumbers()与客户端连接的连接ID不同。

要获取特定的客户端连接ID(specified here),您应该从初始Hub连接的done()方法捕获connectionID,并将其作为全局变量存储到您的脚本中。

如。

var connectionId = null;

$(function() {
//omitted code
    // Connect to signalr hub
    $.connection.hub.start().done(function () {

        connectionId = $.connection.hub.id;
        FetchEmployees();
    });
});

然后在你的aJax调用中提供实际的Hub连接ID而不是随机数。

最后,为了完成它,我还提供了一种方法来检测重新连接,断开连接等,如下所列,更新\清除连接ID的指南,如果它已经更改或断开连接。