ローカルでは動いてたのに、CloudRunにデプロイしたらサーバーにつながらなくなった。
あいかわらずの、なろう作品構文……。笑
それはさておきタイトルのごとく、ローカルでドキュメントやらなんやらに書かれてる形でgRPCで動作してたサーバーとflutterクライアントが、どういうわけかcloudRunにデプロイした途端に繋がらなくなってしまった。
結論から言えば、公式が出してる以下の見本コードの「ChannelCredentials.insecure()」がよろしくなかった模様。
final channel = new ClientChannel('localhost',
port: 50051,
options: const ChannelOptions(
credentials: const ChannelCredentials.insecure()));
final stub = new GreeterClient(channel);
あんまり詳しいことは素人なのでわからんけど、予想としては「そもそもHttpsで通信を組んでるCloudRunにinsecure(つまりセキリュティなし)でつなごうとすると拒否られる」ということかなぁ、と思ってみたり。
実際のところは、詳しい人に聞いてもらってくださいね。こちとら、動けばひとまずよしなのです。←
邪魔なものを消して解決!
で、まあソレだけでは少し不足で、portの方もCloudRunはこのままじゃダメみたいでして。なんでかっていうと、CloudRunにDockerイメージとしてデプロイしてあるから(だと思う)。
[クライアント(flutter)] → [CloudRun: {[Dockerコンテナ: {サーバーイメージ}]}
とまあ、ザックリこんなカタチになっているらしくて(図を書けよ)。
ローカルで試してるときには、クライアントとサーバーがほぼ直接やりとりしていたはずがデプロイすると上記のように色々間に挟まる。これが原因でクライアントでサーバーに書いたPORT指定しても繋がらないわけですね。
まあ、ちゃんとバックエンドを勉強してる人なら知ってて当然な話なんでしょうね……。当たり前過ぎて、いくらネットの海を彷徨っても答えにたどり着かなかったわけですな。Q.E.D!
というわけで、ChannelCredentials.insecure()につづいて、PORTの指定も削っちゃって以下の形。
final channel = new ClientChannel('{CloudRunに設定されてるエンドポイント}');
final stub = new GreeterClient(channel);
って形で、めでたく繋がりましたとさ。(その他部分は適宜、読み替えてね)
消しても多分、問題ない理由。
PORT→CloudRunさんが勝手にコンテナの方へつなげてくれる。
Credential→そもそもCloudRunさんはよしなにHttps(このsはSecureのs。Httpsになってるなら、そもそもSSL通信になってる。)
ということなので、削った部分も概ね問題ナッシングですな。あとは各々要件に合わせてトークン認証やらカスタムドメインで証明書使用やらをしたらよいのではないでしょうか。
これに気づかせてくれた名も知らぬ海外ニキよ。ありがとう(´;ω;`)

コメント