如何使用C# ClientWebSocket读取Azure API Management托管的WebSocket数据?
问题:通过Azure API Management暴露Azure WebPubSub端点后无法接收数据
我正在测试的架构组件如下:
我的目标是通过C#控制台应用的WebSocket客户端,读取由Azure WebPubSub发布到Azure API Management(APIM)的数据。Azure WebPubSub是图中绿色部分的组件,其原生WebSocket端点不对外开放,我通过APIM使用订阅密钥和组织URL将其暴露给外部客户端。
我已借助Azure WebPubSub示例代码实现了直接连接Azure WebPubSub的读写操作,相关代码如下:
直接连接的订阅端代码(AzurePubSubSubscriber)
using System; using System.Threading.Tasks; using Azure.Messaging.WebPubSub; using Websocket.Client; namespace subscriber { class Program { static async Task Main(string[] args) { var connectionString = "Endpoint=https://pubsub.webpubsub.azure.com;AccessKey=myaccesskey;Version=1.0;"; var hub = "myhub"; // 生成客户端访问URL,也可从服务器获取或从门户临时获取 var serviceClient = new WebPubSubServiceClient(connectionString, hub); var url = serviceClient.GetClientAccessUri(); using (var client = new WebsocketClient(url)) { // 禁用自动断开重连,确保客户端在无数据时保持在线 client.ReconnectTimeout = null; client.MessageReceived.Subscribe(msg => Console.WriteLine($"Message received: {msg}")); await client.Start(); Console.WriteLine("Connected."); Console.Read(); } } } }
直接连接的发布端代码(AzurePubSubPublisher)
using System.Threading.Tasks; using Azure; using Azure.Core; using Azure.Messaging.WebPubSub; namespace publisher { class Program { static async Task Main(string[] args) { await Method1(); } public static async Task Method1() { var connectionString = $"Endpoint=https://pubsub.webpubsub.azure.com;AccessKey=myaccesskey;Version=1.0;"; var hub = "myhub"; while (true) { Console.WriteLine("Write your message"); var message = Console.ReadLine(); if (string.IsNullOrEmpty(message)) { return; } // 生成客户端访问URL,也可从服务器获取或从门户临时获取 var serviceClient = new WebPubSubServiceClient(connectionString, hub); await serviceClient.SendToAllAsync(message); } } } }
但当我通过APIM暴露的端点,使用C#控制台应用的ClientWebSocket读取数据时,无法接收数据,不清楚遗漏了什么配置或代码逻辑。连接APIM端点的客户端代码如下:
连接APIM端点的客户端代码
static async Task Main() { await StartWebSocketClient4(); Console.ReadLine(); } static async Task StartWebSocketClient4() { try { Console.Write("Connecting...."); var cts = new CancellationTokenSource(); var socket = new ClientWebSocket(); string wsUri = "wss://myorganization.com/sub?subscription-key=ac3529b7619a383dc6ce6e618dbc9b7614a66"; await socket.ConnectAsync(new Uri(wsUri), cts.Token); Console.WriteLine(socket.State); await Task.Factory.StartNew( async () => { var rcvBytes = new byte[1024 * 1024]; var rcvBuffer = new ArraySegment<byte>(rcvBytes); while (true) { WebSocketReceiveResult rcvResult = await socket.ReceiveAsync(rcvBuffer, cts.Token); byte[] msgBytes = rcvBuffer.Skip(rcvBuffer.Offset).Take(rcvResult.Count).ToArray(); string rcvMsg = Encoding.UTF8.GetString(msgBytes); Console.WriteLine("Received: {0}", rcvMsg); } }, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); } catch(Exception ex) { Console.WriteLine(ex.Message); } }
内容的提问来源于stack exchange,提问作者Zinov
相关产品推荐
相关产品推荐

