You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Hub外部向Blazor SignalR聊天插入消息?

解决Blazor SignalR从Hub外部插入消息的方案

一、C#端直接通过HubContext发送机器人消息

不需要经过前端输入框,后端可直接借助IHubContext向客户端推送消息,适合机器人主动发送回复的场景。

1. 创建消息推送服务

public class ChatBotService
{
    private readonly IHubContext<ChatHub> _hubContext;

    public ChatBotService(IHubContext<ChatHub> hubContext)
    {
        _hubContext = hubContext;
    }

    // 发送消息到指定用户
    public async Task SendBotMessageToUser(string userId, string message)
    {
        await _hubContext.Clients.User(userId).SendAsync("ReceiveMessage", "ChatBot", message);
    }

    // 发送消息到所有在线用户
    public async Task SendBotMessageToAll(string message)
    {
        await _hubContext.Clients.All.SendAsync("ReceiveMessage", "ChatBot", message);
    }
}

2. 注册服务

在Program.cs中注入该服务:

builder.Services.AddScoped<ChatBotService>();

3. 调用服务发送消息

在任意后端逻辑(如API控制器、其他业务服务)中注入ChatBotService即可调用:

public class SomeController : ControllerBase
{
    private readonly ChatBotService _chatBotService;

    public SomeController(ChatBotService chatBotService)
    {
        _chatBotService = chatBotService;
    }

    [HttpGet]
    public async Task<IActionResult> TriggerBotReply(string userId)
    {
        await _chatBotService.SendBotMessageToUser(userId, "这是机器人的自动回复");
        return Ok();
    }
}

二、前端处理点击链接发送预定义消息

针对机器人消息中的链接,通过Blazor组件自身方法处理,避免JS直接操作DOM导致的双向绑定失效问题。

1. Blazor组件核心代码

<div id="chatComponent">
    <input @bind="_messageInput" placeholder="输入消息..." />
    <button @onclick="SendMessage">发送</button>

    <div class="chat-messages">
        @foreach (var msg in _chatMessages)
        {
            <div>
                <strong>@msg.User:</strong>
                @if (msg.IsBotLink)
                {
                    <a @onclick="() => SendPredefinedMessage(msg.PredefinedText)">@msg.DisplayContent</a>
                }
                else
                {
                    @msg.DisplayContent
                }
            </div>
        }
    </div>
</div>

@code {
    private string _messageInput;
    private HubConnection _hubConnection;
    private List<ChatMessage> _chatMessages = new();

    protected override async Task OnInitializedAsync()
    {
        _hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chatHub"))
            .Build();

        _hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            // 解析机器人消息(示例:判断是否包含链接)
            var isBotLink = message.Contains("[链接]");
            var chatMsg = new ChatMessage
            {
                User = user,
                DisplayContent = isBotLink ? "点击查看详情" : message,
                IsBotLink = isBotLink,
                PredefinedText = isBotLink ? "这是预定义的回复内容" : null
            };

            _chatMessages.Add(chatMsg);
            StateHasChanged();
        });

        await _hubConnection.StartAsync();
    }

    private async Task SendMessage()
    {
        if (!string.IsNullOrEmpty(_messageInput) && _hubConnection.State == HubConnectionState.Connected)
        {
            await _hubConnection.SendAsync("SendMessage", "当前用户", _messageInput);
            _messageInput = string.Empty;
        }
    }

    // 处理预定义消息发送
    private async Task SendPredefinedMessage(string predefinedText)
    {
        _messageInput = predefinedText;
        await SendMessage();
    }

    private class ChatMessage
    {
        public string User { get; set; }
        public string DisplayContent { get; set; }
        public bool IsBotLink { get; set; }
        public string PredefinedText { get; set; }
    }
}

2. 可选:JS调用Blazor组件方法

如果必须通过JS触发(如第三方渲染的消息内容),可通过DotNet.invokeMethodAsync调用组件的公开方法:

Blazor组件添加可调用方法

[JSInvokable]
public async Task SendPredefinedMessageFromJS(string predefinedText)
{
    _messageInput = predefinedText;
    await SendMessage();
}

JS代码触发调用

function triggerPredefinedMessage(message) {
    DotNet.invokeMethodAsync('你的项目程序集名称', 'SendPredefinedMessageFromJS', message);
}

在消息的HTML链接中使用:

<a href="javascript:void(0);" onclick="triggerPredefinedMessage('预定义消息内容')">点击发送预定义消息</a>

内容的提问来源于stack exchange,提问作者Daniel Schneider

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 11:45:24