Проблема обновления данных из реального времени SQL с SignalR - PullRequest
0 голосов
/ 08 января 2020

Я использую SignalR для обновления записей в реальном времени и отображения их в таблице для клиентской стороны с подключением к SQL, я устанавливаю sh соединение, когда я запускаю приложение, они загружают все данные, но когда Я обновляю БД, обновление не отображается в таблице на стороне клиента, но когда я даю F5 (refre sh) в браузере, текущие данные просто отображаются. Я не могу найти ошибку, я также не вижу никаких ошибок консоли. Я прикрепил код для предложений :) спасибо

Клиент:

<body>
<h1>Hola</h1>

<div class="table table-responsive">
    <table id="tbl-productos" class="table table-bordered table-striped"></table>
</div>

<script src="~/jquery/jquery.min.js"></script>
<script src="~/aspnet/signalr/dist/browser/signalr.min.js"></script>

<script>
    $(function () {
        fnCrearTabla();
    });

    function fnCrearTabla() {
        var tabla = $("#tbl-productos");
        $.ajax({
            url: "/Home/listadoProductos",
            type: "GET",
            contentType: "application/json; charset-utf-8",
            dataType: "json",
            success: function (data) {
                if (data.length > 0) {
                    //tabla.empty();
                    var thead = "<tr>";
                    thead += "<th>id</th>"
                    thead += "<th>nombre</th>"
                    thead += "<th>precio</th>"
                    thead += "<th>Stock</th>"
                    thead += "</tr>"

                    tabla.append(thead);

                    var array = [];
                    var tbody = "";

                    for (var i = 0; i < data.length; i++) {
                        tbody += "<tr>";
                        tbody += "<td>" + data[i].id + "</td>"
                        tbody += "<td>" + data[i].nombre + "</td>"
                        tbody += "<td>" + data[i].precio + "</td>"
                        tbody += "<td>" + data[i].stock + "</td>"
                        tbody += "</tr>"
                    }

                    array.push(tbody);
                    tabla.append(array.join(""));
                }
            },
            error: function (e) {
                console.error(e);
            }
        });

    }

    var connection = new signalR.HubConnectionBuilder().withUrl("http://localhost:63257/tablaHub").build();
    //connection.serverTimeoutInMilliseconds = 100000; // 100 second}

    connection.on("ActualizarGrilla", function () {
        fnCrearTabla();
    });

    connection.start().catch(function () {
         console.error(e);
    });
</script>

Контроллер:

public class HomeController : Controller
{
    private readonly IProductoServicio _productoServicio;

    public HomeController(IProductoServicio productoServicio)
    {
        this._productoServicio = productoServicio;
    }

    public IActionResult Index()
    {
        return View();
    }

    public JsonResult listadoProductos()
    {
        var data = _productoServicio.Listado().ToList();
        return Json(data);
    }
}

Startup.cs

public class Startup
{
    private readonly IWebHostEnvironment _webHostEnvironment;
    private readonly IConfiguration _configuration;

    public Startup(IWebHostEnvironment webHostEnvironment)
    {
        this._webHostEnvironment = webHostEnvironment;

        var builder = new ConfigurationBuilder()
            .SetBasePath(_webHostEnvironment.ContentRootPath)
            .AddJsonFile("appsettings.json")
            .AddEnvironmentVariables();
        _configuration = builder.Build();
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton(_configuration);

        #region IOC

        services.AddScoped<IProductoRepositorio, ProductoRepositorio>();
        services.AddScoped<IProductoServicio, ProductoServicio>();

        #endregion

        services.AddSignalR();
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseDeveloperExceptionPage();
        app.UseStaticFiles();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapHub<TablaHub>("/tablaHub");
            endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

И здесь все происходит, реализуется класс --->

ProdcutoRepositorio.cs:

public class ProductoRepositorio : IProductoRepositorio
{
    private readonly IConfiguration _configuration;
    private readonly IHubContext<TablaHub> _tablaHub;

    public ProductoRepositorio(IConfiguration configuration,
                               IHubContext<TablaHub> tablaHub)
    {
        this._configuration = configuration;
        this._tablaHub = tablaHub;
    }

    public IEnumerable<Producto> Get()
    {
        List<Producto> listProducto = null;
        Producto oProducto = null;
        SqlDependency dependency = null;

        var connectionString = _configuration.GetConnectionString("dbconnection");

        using (SqlConnection cn = new SqlConnection(connectionString))
        {
            try
            {
                cn.Open();
                SqlCommand cmd = new SqlCommand("upsGetProductos", cn);
                cmd.CommandType = CommandType.StoredProcedure;

                #region SqlDependecy

                cmd.Notification = null;
                dependency = new SqlDependency(cmd);
                dependency.OnChange += DetectarCambios;
                SqlDependency.Start(connectionString);

                #endregion

                SqlDataReader dr = cmd.ExecuteReader();

                if (dr.HasRows)
                {
                    listProducto = new List<Producto>();

                    while (dr.Read())
                    {
                        oProducto = new Producto()
                        {
                            Id = dr.IsDBNull(dr.GetOrdinal("Id")) ? -1 : dr.GetInt32(dr.GetOrdinal("Id")),
                            Nombre = dr.IsDBNull(dr.GetOrdinal("Nombre")) ? "nodata" : dr.GetString(dr.GetOrdinal("Nombre")),
                            Precio = dr.IsDBNull(dr.GetOrdinal("Precio")) ? Convert.ToDecimal(0) : dr.GetDecimal(dr.GetOrdinal("Precio")),
                            Stock = dr.IsDBNull(dr.GetOrdinal("Stock")) ? -1 : dr.GetInt32(dr.GetOrdinal("Stock"))
                        };
                        listProducto.Add(oProducto);
                    }
                }
                return listProducto;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
    }

    public void DetectarCambios(object sender, SqlNotificationEventArgs e)
    {
        if (e.Type == SqlNotificationType.Change)
        {
            _tablaHub.Clients.All.SendAsync("ActualizarGrilla");
        }

        Get();
    }

    public void Dispose()
    {
        GC.SuppressFinalize(this);
    }
}

И мой класс-концентратор ... TablaHub:

public class TablaHub : Hub
{
}

1 Ответ

0 голосов
/ 09 января 2020

Я думаю, что вы можете столкнуться с проблемой кеширования, так как вы делаете ajax вызов. Вы можете начать с просмотра сетевого трафика c в своем браузере, чтобы узнать, действительно ли он выполняет вызовы на сервер для получения данных при внесении изменений. Это было бы полезно для отладки, если вы добавляете некоторые записи консоли, возможно, внутри fnCrearTabla, чтобы проверить, что вы получаете сообщения от signalR. Следующий код отключит кеширование

$.ajax({  cache: false,  ...});
...