为什么我会收到此异常 (gRCP)

Why do I get this exception (gRCP)

我尝试在gRPC中做一个BlackJack游戏来练习,但是我不明白这个流传输。

任务(服务器):

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 (await responseStream.MoveNext()) 得到一个异常,因为输入参数,但不知道是什么错了。

RpcException:

'Grpc.Core.RpcException' 类型的异常发生在 mscorlib.dll 但未在用户代码中处理 附加信息:Status(StatusCode=Unknown, Detail="Exception was thrown by handler.")

在服务器的控制台中:

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 并再次阅读等等吗?

这看起来像是您的代码中的一个问题,大部分与 gRPC 无关。

从错误消息中可以明显看出它发生在服务器端处理程序内部。我们去那里看看。

第一行是 int.Parse(dealAmount.ToString());,"dealAmount" 是协议缓冲区消息,ToString() 给出其 JSON 表示(例如 { "Value": 123 }或者)。这显然不是 int.Parse 可以接受的格式(因此例外 "System.FormatException: Input string was not in a correct format.")。

将 protobuf 消息转换为字符串然后尝试解析是没有意义的 - 生成的 "Amount" class 已经允许您访问所需的所有字段,并且类型正确。