此clationt是处置信号的

发布于 2025-01-23 12:11:06 字数 3462 浏览 0 评论 0原文

在用户连接时,一切进展顺利。当我有一个产品更新(可供出售)时,onproductStartsales事件被调用。 但是存在一个问题,因为介绍了集线器中的客户端列表,因此消息不会出现在客户端。 这是我的中心的代码。

public class SalesHub : Hub
{
    private readonly ProductDatabaseListener _listener;

    public SalesHub(ProductDatabaseListener listener)
    {
        _listener = listener ?? throw new ArgumentNullException(nameof(listener));
        _listener.OnProductStartSales += (s, p) => ProductStartSales(p);
        _listener.OnProductDataChanged += (s, p) => ProductDataChanged(p);
    }

    public async Task ListenProduct(string productId)
    {
        await this.Groups.AddToGroupAsync(Context.ConnectionId, productId);
    }

    private async Task ProductStartSales(Product product)
    {
        await this.Clients.Group(product.Id).SendAsync("StartSales", product.Id);
        // await this.Clients.All.SendAsync("StartSales", product.Id);
    }

    private async Task ProductDataChanged(Product product)
    {
        await this.Clients.Group(product.Id).SendAsync("DataChanged", product);
    }
}

这是听众的守则。

public class ProductDatabaseListener
{
    private readonly IRepository<Product> _repository;
    private readonly object _locker = new object();

    public ProductDatabaseListener(IServiceProvider serviceProvider)
    {
        using (var scope = serviceProvider.CreateScope())
        {
            _repository = scope.ServiceProvider.GetRequiredService<IRepository<Product>>() ?? throw new ArgumentNullException(nameof(_repository));
        }
    }

    public event EventHandler<Product> OnProductStartSales;
    public event EventHandler<Product> OnProductDataChanged;

    // Need better performance...
    public async Task ListenMongo()
    {
        while (true)
        {
            var products = await _repository.GetRange(0, int.MaxValue);
            var date = DateTime.Now;
            List<Task> tasks = new List<Task>();

            foreach (var product in products)
            {
                if (product.IsSalesStart)
                {
                    continue;
                }

                if (product.StartOfSales <= date)
                {
                    product.IsSalesStart = true;
                    OnProductStartSales?.Invoke(this, product);
                    tasks.Add(_repository.Update(product));
                }
            }

            Task.WaitAll(tasks.ToArray());

            await Task.Delay(1000);
        }
    }
}

这是客户端代码

"use strict";

var connection = new signalR.HubConnectionBuilder().withUrl("/salesHub").build();

connection.on("ReceiveMessage", function (id) {
    var li = document.createElement("li")
    document.getElementById("fromHub").appendChild(li)
    li.textContent = id;
});

connection.on("startSales", function (id) {
    var productId = document.getElementById("objectId").getAttribute("value");
    if (productId == id) {
        var button = document.getElementById("buy")
        button.hidden = false
    }
});

connection.logging = true;

connection.start().then(function () {
    var productId = document.getElementById("objectId").getAttribute("value");
    connection.invoke("ListenProduct", productId).catch(function (err) {
        return console.error(err.toString());
    });
    event.preventDefault();
}).catch(function (err) {
    return console.error(err.toString());
});

At the time of the user's connection, everything is going well. When I have a product update (it becomes available for sale), the OnProductStartSales event is called.
But there is one problem, the message does not come to the client because the list of clients in the hub is disposed.
Here is the code of my hub.

public class SalesHub : Hub
{
    private readonly ProductDatabaseListener _listener;

    public SalesHub(ProductDatabaseListener listener)
    {
        _listener = listener ?? throw new ArgumentNullException(nameof(listener));
        _listener.OnProductStartSales += (s, p) => ProductStartSales(p);
        _listener.OnProductDataChanged += (s, p) => ProductDataChanged(p);
    }

    public async Task ListenProduct(string productId)
    {
        await this.Groups.AddToGroupAsync(Context.ConnectionId, productId);
    }

    private async Task ProductStartSales(Product product)
    {
        await this.Clients.Group(product.Id).SendAsync("StartSales", product.Id);
        // await this.Clients.All.SendAsync("StartSales", product.Id);
    }

    private async Task ProductDataChanged(Product product)
    {
        await this.Clients.Group(product.Id).SendAsync("DataChanged", product);
    }
}

Here is the code of listener.

public class ProductDatabaseListener
{
    private readonly IRepository<Product> _repository;
    private readonly object _locker = new object();

    public ProductDatabaseListener(IServiceProvider serviceProvider)
    {
        using (var scope = serviceProvider.CreateScope())
        {
            _repository = scope.ServiceProvider.GetRequiredService<IRepository<Product>>() ?? throw new ArgumentNullException(nameof(_repository));
        }
    }

    public event EventHandler<Product> OnProductStartSales;
    public event EventHandler<Product> OnProductDataChanged;

    // Need better performance...
    public async Task ListenMongo()
    {
        while (true)
        {
            var products = await _repository.GetRange(0, int.MaxValue);
            var date = DateTime.Now;
            List<Task> tasks = new List<Task>();

            foreach (var product in products)
            {
                if (product.IsSalesStart)
                {
                    continue;
                }

                if (product.StartOfSales <= date)
                {
                    product.IsSalesStart = true;
                    OnProductStartSales?.Invoke(this, product);
                    tasks.Add(_repository.Update(product));
                }
            }

            Task.WaitAll(tasks.ToArray());

            await Task.Delay(1000);
        }
    }
}

Here is the client code

"use strict";

var connection = new signalR.HubConnectionBuilder().withUrl("/salesHub").build();

connection.on("ReceiveMessage", function (id) {
    var li = document.createElement("li")
    document.getElementById("fromHub").appendChild(li)
    li.textContent = id;
});

connection.on("startSales", function (id) {
    var productId = document.getElementById("objectId").getAttribute("value");
    if (productId == id) {
        var button = document.getElementById("buy")
        button.hidden = false
    }
});

connection.logging = true;

connection.start().then(function () {
    var productId = document.getElementById("objectId").getAttribute("value");
    connection.invoke("ListenProduct", productId).catch(function (err) {
        return console.error(err.toString());
    });
    event.preventDefault();
}).catch(function (err) {
    return console.error(err.toString());
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文