Как заставить C# WebSocketClient прослушивать сообщения в непрерывном режиме - PullRequest
0 голосов
/ 14 февраля 2020

Я пишу программу (на самом деле это игра в Unity), которая должна действовать как клиент для сервера Websocket, который работает отдельно и работает.

Я использую System.Net.Websockets ClientWebSocket , Я открыл соединение, я могу отправлять сообщения, но в отличие от клиента Javascript, где я настраивал бы функцию обратного вызова, которая запускалась бы каждый раз, когда клиент веб-сокета получал сообщение. Мне трудно понять, для чего предназначен поток C# API.

Вот обработчик сообщения, который я написал:

public async Task HandleMessages() {
        using (var ms = new MemoryStream()) {
            var messageBuffer = WebSocket.CreateClientBuffer(8192, 8192);
            WebSocketReceiveResult result;
            do {
                result = await ws.ReceiveAsync(messageBuffer, CancellationToken.None);
                ms.Write(messageBuffer.Array, messageBuffer.Offset, result.Count);
            }
            while (!result.EndOfMessage);

            if (result.MessageType == WebSocketMessageType.Text) {
                var msgString = Encoding.UTF8.GetString(ms.ToArray());
                Debug.Log(msgString);
                var message = JsonConvert.DeserializeObject<Dictionary<String, String>>(msgString);
                if (message["roomCode"] == RoomCode.ToLower()) {
                    // Message was intended for us!
                    Debug.Log("[WS] Got a message of type " + message["messageType"]);
                }
            }
        }
    }

Итак, после первоначального открытия соединения с Websocket, если я вызову это:

await Task.WhenAll(HandleMessages());

, тогда он будет обрабатывать первое входящее сообщение, но не последующие. Я пробовал много разных вещей, но не могу понять, как заставить эту задачу запускаться каждый раз, когда приходит сообщение.

Кто-нибудь знает что-нибудь по этому поводу?

1 Ответ

0 голосов
/ 14 февраля 2020

Оказывается, в этой ситуации, как всегда, был хороший элемент пользовательской ошибки.

Я не понимал некоторых базовых c концепций веб-сокетов, поэтому, когда я думал, что вещаю Сообщения с моего сервера я действительно отправлял только определенным клиентам. С улучшениями, предложенными Mar c Gravell и большим количеством часов работы над моим C# клиентским кодом, теперь выглядит так:

public async Task HandleMessages() {
        try {
            using (var ms = new MemoryStream()) {
                while (ws.State == WebSocketState.Open) {
                    WebSocketReceiveResult result;
                    do {
                        var messageBuffer = WebSocket.CreateClientBuffer(1024, 16);
                        result = await ws.ReceiveAsync(messageBuffer, CancellationToken.None);
                        ms.Write(messageBuffer.Array, messageBuffer.Offset, result.Count);
                    }
                    while (!result.EndOfMessage);

                    if (result.MessageType == WebSocketMessageType.Text) {
                        var msgString = Encoding.UTF8.GetString(ms.ToArray());
                        var message = JsonConvert.DeserializeObject<Dictionary<String, String>>(msgString);
                        if (message["roomCode"].ToLower() == RoomCode.ToLower()) {
                            Debug.Log("[WS] Got a message of type " + message["messageType"]);
                            // Message was intended for us!
                            switch (message["messageType"]) {
                                // handle messages here, unimportant to stackoverflow
                            }
                        }
                    }
                    ms.Seek(0, SeekOrigin.Begin);
                    ms.Position = 0;
                }
            }
        } catch (InvalidOperationException) {
            Debug.Log("[WS] Tried to receive message while already reading one.");
        }
    }

После того, как я настроил сервер на фактическую трансляцию сообщений, я думал, что вещаю (переберите всех клиентов и отправьте сообщение), теперь он будет читать несколько сообщений. Еще раз спасибо за помощь, и, надеюсь, это поможет в будущем другим, кто плохо знаком с веб-сокетами, есть что проверить на

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...