Почему я получаю это исключение (gRCP) - PullRequest
0 голосов
/ 02 января 2019

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

Задача (Server):

public async Task Deal(Amount dealAmount, IServerStreamWriter<Card> responseStream, ServerCallContext context)
    {
        this.dealAmount = int.Parse(dealAmount.ToString());
        if (deck.Count < 17)
        {
            deck.Clear();
            DeckRead();
            Shuffle();
        }

        FirstDeal();

        Card temp = new Card();
        temp.Card_ = player[0];
        await responseStream.WriteAsync(temp);
        temp.Card_ = player[1];
        await responseStream.WriteAsync(temp);
        temp.Card_ = dealer[0];
        await responseStream.WriteAsync(temp);
    }

Клиент:

private async void btDeal_Click(object sender, EventArgs e)
    {
        Amount dAmount = new Amount();
        dAmount.Amount_ = Convert.ToInt32(udDeal.Value);
        string newCard;

        using (var call = client.Deal(dAmount))
        {
            var responseStream = call.ResponseStream;
            int y = 0;
            while (await responseStream.MoveNext())
            {
                newCard = responseStream.Current.ToString();

                if(y == 3)
                {
                    dealer.Add(newCard);
                }
                else
                {
                    player.Add(newCard);
                    y++;
                }
            }
        }

        dealerCards[0].Load(string.Format("Images/cards/{0}.png", dealer[0]));
        dealerCards[1].Load(string.Format("Images/cards/Back/gray_back.png"));
        playerCards[0].Load(string.Format("Images/cards/{0}.png", player[0]));
        playerCards[1].Load(string.Format("Images/cards/{0}.png", player[1]));

        lblDealerAmount.Text = int.Parse(dealer[0].Substring(0, 2)).ToString();
        lblPlayerAmount.Text = PlayerAmount().ToString();

        money = money - dealAmount;
        lblAmount.Text = money.ToString();
        btDeal.Enabled = false;
    }

прото:

rpc Deal(Amount) returns (stream Card) {}

message Card {
   string card=1;
}

message Amount {
  int32 amount=1;
}

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

Прежде всего, я получаю исключение при while (ожидайте responseStream.MoveNext ()) из-за входных параметров, но не знаю, что не так.

RpcException:

Исключение типа 'Grpc.Core.RpcException' произошло в mscorlib.dll, но не было обработано в коде пользователя Дополнительная информация: Status (StatusCode = Unknown, Detail = "Исключение было сгенерировано обработчиком.")

В консоли сервера:

E02/01/2019 13:46:47 Grpc.Core.Internal.ServerStreamingServerCallHandler`2 Exception occured in handler. System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Int32.Parse(String s)
   at BlackJackServer.BJS.<Deal>d__14.MoveNext() in C:\Users\tesa3\Desktop\GRPC BEAD\grpc\grpc-master\examples\csharp\BlackJack\BlackJackServer\Program.cs:line 108
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at Grpc.Core.Internal.ServerStreamingServerCallHandler`2.<HandleCall>d__0.MoveNext()

С другой стороны, я не знаю, правильно ли я использую WriteAsync в этом случае. Я имею в виду, я точно знаю, что клиент получит три строки. Могу ли я просто прочитать текущий, а затем MoveNext и снова прочитать и так далее?

1 Ответ

0 голосов
/ 10 января 2019

Это похоже на проблему в вашем коде, которая в основном не связана с gRPC.

Из сообщения об ошибке очевидно, что это происходит внутри обработчика на стороне сервера.Давайте посмотрим там.

Самая первая строка там int.Parse(dealAmount.ToString());, "dealAmount" - это сообщение буфера протокола, а ToString () дает его представление JSON (например, что-то вроде { "Value": 123 } или около того),Это явно не тот формат, который может принять int.Parse (отсюда исключение «System.FormatException: входная строка была не в правильном формате.»).

Преобразование в сообщение protobuf в строку и затем попыткаparse не имеет смысла - сгенерированный класс «Amount» уже дает вам доступ ко всем нужным полям правильного типа.

...