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

时间:2019-01-02 12:27:46

标签: c# streaming rpc

我尝试用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;
    }

proto:

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

message Card {
   string card=1;
}

message Amount {
  int32 amount=1;
}

我知道这不是有史以来最干净的代码,但是现在我只想了解gRCP的工作方式。因此,此任务将前四张卡发给玩家,两张发给玩家,两张发给发牌人,但其中一张发牌者背对后方,因此客户将获得三张卡(他的卡中有2张,发牌人的卡是1张参见)。

首先,由于输入参数,我在 while(await responseStream.MoveNext())处出现异常,但不知道出了什么问题。

RpcException:

mscorlib.dll中发生了'Grpc.Core.RpcException'类型的异常,但未在用户代码中处理 附加信息: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 :(得分:1)

这看起来像是代码中的问题,与gRPC几乎没有关系。

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

第一行是int.Parse(dealAmount.ToString());,“ dealAmount”是协议缓冲区消息,ToString()给出了其JSON表示形式(例如,类似{ "Value": 123 }之类的东西)。显然,这不是int.Parse可以接受的格式(因此出现异常“ System.FormatException:输入字符串的格式不正确。”)。

将protobuf消息转换为字符串然后尝试解析没有任何意义-生成的“金额”类已经使您可以使用正确的类型访问所需的所有字段。