如何将WPF应用连接至Azure SignalR Service?
解决方案:WPF直接连接Azure SignalR Service(无服务器模式)
Azure SignalR Service本身是中继服务,无法直接作为独立Hub服务器使用。如果你不想部署自建后端,可以采用Azure Functions + Azure SignalR Service无服务器模式实现,以下是具体步骤:
1. 配置Azure SignalR Service为无服务器模式
- 登录Azure Portal,找到你的SignalR Service实例
- 进入「设置」页面,将「服务模式」改为无服务器,保存配置
2. 创建Azure Functions项目(处理消息逻辑)
新建Azure Functions项目,添加两个核心函数:
(1)Negotiate函数(用于客户端获取连接凭证)
该函数为WPF客户端提供合法的SignalR连接URL和AccessToken:
[FunctionName("Negotiate")] public static SignalRConnectionInfo Negotiate( [HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req, [SignalRConnectionInfo(HubName = "draftchat")] SignalRConnectionInfo connectionInfo) { return connectionInfo; }
(2)SendMessage函数(用于广播消息)
该函数接收客户端发送的消息,通过SignalR Service广播给所有在线客户端:
[FunctionName("SendMessage")] public static async Task SendMessage( [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req, [SignalR(HubName = "draftchat")] IAsyncCollector<SignalRMessage> signalRMessages) { var body = await new StreamReader(req.Body).ReadToEndAsync(); var messageObj = JsonConvert.DeserializeObject<Message>(body); await signalRMessages.AddAsync(new SignalRMessage { Target = "ReceiveMessage", Arguments = new[] { messageObj.User, messageObj.Message } }); } public class Message { public string User { get; set; } public string Message { get; set; } }
配置Functions连接字符串
在Azure Functions应用的「配置」页面,添加名为AzureSignalRConnectionString的应用设置,值为你SignalR Service实例的连接字符串(从SignalR实例的「密钥」页面获取)。
3. 修改WPF客户端代码
客户端需要先调用Negotiate接口获取合法连接信息,再建立SignalR连接:
private HubConnection? _connection; private async Task ConnectToSignalR() { // 调用Functions的Negotiate接口获取连接凭证 var negotiateClient = new HttpClient(); var negotiateResponse = await negotiateClient.GetFromJsonAsync<SignalRConnectionInfo>( "https://你的函数应用名称.azurewebsites.net/api/negotiate"); if (negotiateResponse == null) { Messages.Items.Add("获取连接凭证失败"); return; } // 使用凭证创建SignalR连接 _connection = new HubConnectionBuilder() .WithUrl(negotiateResponse.Url, options => { options.AccessTokenProvider = () => Task.FromResult(negotiateResponse.AccessToken); }) .WithAutomaticReconnect() .Build(); // 监听消息推送 _connection.On<string, string>("ReceiveMessage", (user, message) => { Dispatcher.Invoke(() => { Messages.Items.Add($"{user}: {message}"); }); }); try { await _connection.StartAsync(); Messages.Items.Add("连接成功"); openConnection.IsEnabled = false; sendMessage.IsEnabled = true; } catch (Exception ex) { Messages.Items.Add($"连接失败: {ex.Message}"); } } // 发送消息方法 private async Task SendMessageAsync(string user, string message) { if (_connection == null || _connection.State != HubConnectionState.Connected) { Messages.Items.Add("未连接到SignalR服务"); return; } // 调用Functions的SendMessage接口发送消息 var httpClient = new HttpClient(); await httpClient.PostAsJsonAsync( "https://你的函数应用名称.azurewebsites.net/api/sendmessage", new { User = user, Message = message }); } // 用于接收Negotiate返回数据的模型 public class SignalRConnectionInfo { public string Url { get; set; } public string AccessToken { get; set; } }
关键说明
- 你之前直接连接SignalR Service地址失败的核心原因:缺少合法的身份凭证(AccessToken),且无后端Hub处理连接请求。
- 无服务器模式下,所有Hub方法调用必须通过Azure Functions转发,SignalR Service仅负责消息中继。
内容的提问来源于stack exchange,提问作者chompsey
相关产品推荐
相关产品推荐

