【问题标题】:SignalR - Send message AllExcept() dont work (Aspnet Core 2.1)SignalR - 发送消息 AllExcept() 不起作用(Aspnet Core 2.1)
【发布时间】:2020-10-09 03:47:20
【问题描述】:

我正在尝试向连接到集线器的所有用户发送消息,但向控制器发出请求的用户除外,但 AllExcept () 方法正在向所有用户发送消息。

我将解释我到目前为止所做的事情。

我有一个使用 signalR 3.18 的 Aspnet Core 2.1 应用程序(我不确定版本,但它是> 3)

这是我的 Hub 课程

public class MesHub : Hub
    {
        public async Task Cadastrar()
        {
            await Clients.All.SendAsync("ReceberCadastro", true, "deu certo");
        }

        public override Task OnConnectedAsync()
        {
            string name = Context.User.Identity.Name;

            Groups.AddToGroupAsync(Context.ConnectionId, name);

            return base.OnConnectedAsync();
        }
    }

我通过控制器中的依赖注入使用集线器,所以请跟随我的控制器。 我不会发布我的整个控制器,只发布一部分。

private readonly TipoEstoqueService _context;
        private readonly UsuarioService _userContext;
        private readonly IHubContext<MesHub> _hubContext;

        public TipoEstoqueController(TipoEstoqueService context, 
            UsuarioService userContext, 
            IHubContext<MesHub> hubContext)
        {
            _context = context;
            _userContext = userContext;
            _hubContext = hubContext;
        }


[HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create(TipoEstoque obj)
        {
            string idUser = this.User.Identity.Name;
            /*verifica se post é valido. Se  o js estiver desabilitado no navegador do usuario
            ele consegue dar post vazio, esse if serve para previnir isso*/
            if (!ModelState.IsValid)
            {
                return View(obj);//teve algum campo q n foi preenchido
            }

            if (await _context.VerificaNome(obj.Nome, -1)) // se ja existe o nome
            {
                await _hubContext.Clients.Group(idUser).SendAsync("TipoEstoqueCadastradoFalha", true, "Este Nome já existe");
                return Json("Erro: Este Nome já existe");
            }
            
            try
            {
                await _context.InsertAsync(obj);
                
                //informa ao usuario q esta cadastrando, q o cadastro funcionou
                await _hubContext.Clients.Group(idUser).SendAsync("TipoEstoqueCadastradoSucesso", true, "O Tipo do Estoque foi adicionado com sucesso.");
                //atualiza a lista pra tds
                await _hubContext.Clients.All.SendAsync("AtualizaListagemTipoEstoque", true);
                //informa para tds q foi feito um novo cadastro
                await _hubContext.Clients.AllExcept(idUser).SendAsync("NovoTipoEstoqueFoiCadastradoSucesso", true, idUser+" cadastrou um Tipo de Estoque.");
                
            }
            catch (Exception)
            {
                await _hubContext.Clients.Group(idUser).SendAsync("TipoEstoqueCadastradoFalhaException", true, "Houve uma exceção ao tentar cadastrar, tente novamente.");
            }
            
            return Json("Success");
        }

在我的控制器中,在create方法和try中,我通过SignalR发送消息,所有发送正常,但是这部分没有做它应该做的。

//informa para tds q foi feito um novo cadastro
                await _hubContext.Clients.AllExcept(idUser).SendAsync("NovoTipoEstoqueFoiCadastradoSucesso", true, idUser+" cadastrou um Tipo de Estoque.");

据我了解,此摘录应将消息发送给所有用户,但调用 create 方法的用户除外,但这并没有发生。消息无一例外地发送给所有人。

在我的 _Layout.cshtml 中,我有以下代码可以连接到集线器

<script>
    var connection = new signalR.HubConnectionBuilder().withUrl("/MesHub").build();
    var usuarioConectado;
    function ConnectionStart() {
        Object.defineProperty(WebSocket, 'OPEN', { value: 1, });
        connection.start().then(function () {
            $(".status-user").css({ backgroundColor: '#00dc00' });
            usuarioConectado = true;
        }).catch(function (err) {
            console.error(err.toString());
            console.log(usuarioConectado);
            $(".status-user").css({ backgroundColor: '#ff0303' });
            setTimeout(ConnectionStart(), 5000);
        });
    }

    // Essa linha tenta reconectar ao hub caso a conexão caia do lado do cliente
    connection.onclose(async () => { await ConnectionStart(); });

    ConnectionStart();
</script>

这里有一个名为 Index.cshtml 的视图,它等待来自 Hub 的消息

//Cadastro realizado com sucesso
    connection.on("TipoEstoqueCadastradoSucesso", function (sucesso, msg) {
        if (sucesso) {
            swal({
                title: "Sucesso!",
                text: "Item criado com sucesso.",
                confirmButtonColor: "#fff0",
                type: "success",
                timer: 1300
            });
            $("#divModal").modal('hide');
        }
    });

    //informa a tds q foi feito um novo cadastro
    connection.on("NovoTipoEstoqueFoiCadastradoSucesso", function (sucesso, msg) {
        if (sucesso) {
            new PNotify({
                title: 'Adicionado!',
                text: msg,
                type: 'success',
                addclass: 'alert-styled-left alert-arrow-left',
            });
        }
    });

谁能告诉我我做错了什么??

如果缺少任何信息,请告诉我,我会发布。

【问题讨论】:

    标签: asp.net-core signalr


    【解决方案1】:

    Identity 中的 userId 与 Hub 上下文中的 ConnectionId 不同。

    await _hubContext.Clients.AllExcept(idUser)... 
    

    上面的这个 idUser 是 Hub 的未知用户

    您需要在 Hub 的连接 ID 上关联身份的 UserId:

    1 - 声明下面的类:

    public class CustomUserIdProvider : IUserIdProvider
    {
        public virtual string GetUserId(HubConnectionContext connection)
        {
            return connection.GetHttpContext().User?.FindFirst(ClaimTypes.NameIdentifier)?.Value
        }
    }
    

    在您的 DI 设置中,添加以下行:

    services.AddSingleton<IUserIdProvider, CustomUserIdProvider>();
    

    之后,再次测试!

    注意:我认为您不需要此行来覆盖 OnConnectedAsync:

     Groups.AddToGroupAsync(Context.ConnectionId, name);
    

    对于特定用户的发送消息,您可以这样写(其中 idUser 是身份的 id):

    await _hub.Clients.Users(idUser).SendAsync ...
    

    【讨论】:

    • 首先感谢您的回复。我有一个问题,CustomUserIdProvider 类,我可以在任何地方声明它吗?
    • 我按照你说的做了修改,但是没有用。消息正在无限制地发送给所有用户。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多