Azure WebPubSub Service+Azure FunctionsとUnityで通信したい
これになりました、泣いています
具体的にはUnityクライアントで使っていたSignalRライブラリが急にビルドできなくなって
_人人人人人人_
> 突然の死 <
 ̄Y^Y^Y^Y^Y^Y^
ってなってます
どうやっても治らないので
バックエンド丸ごとsignalrからWebPubSubに移行したい
ソケット鯖をherokuとかに立ててしのごうかなーと思ったんだけど
せっかくなので気になっていたPubSubを試したいし
なんならサーバレスモードもありながらSignalRよりもクライアントの扱いが簡単そう
Azure Web PubSub サービスは、Azure SignalR Service に代わるものではありません。
まだプレビュー機能みたいなんでそこがちょっと心配だけど
とりあえず使ってみよう!
azure functionsとの統合は、こちらのサンプルがそのまま参考になりそう
Azure Web PubSub Seriviceの公式ドキュメントはこちら
Azure Web PubSubはいいとして、System.Net.WebSocketがちょっとめんどくさいなぁと感じた
Web APIのとは違って、イベントベースの記述ができていない(なんか前にも同じこと思った気がした)
そうか、RecieveAsyncが呼ばれるまで待たなくちゃいけないんだ......めんどくさ......
WebSocketクラスのdocs
Azure.Messaging.WebPubSubのNuGetパッケージ
もしかしたらこいつ使えるかも?
SignalRの二の舞にならないといいが......
githubのドキュメント
Azure Functionsのトリガー。バインディングス
WebSOcket.Clientというサードパーティ製のライブラリがるらしい
こっちのほうが使いやすそう
Web PubSubでチャットを作るチュートリアルがわかりやすい
手元の環境でPubSubのFunctionsを動かしてみたら
なぜかPubSubConnectionのバインドが見つからないと言われてしまった
そもそもこのバインドがあるのはFunctionsのExtensionBundle3.3.0~らしいので
一応host.jsobも更新したんだけど、ダメでしたね
おっ、別のPCで試したらいい感じに動いてくれた
extensionBundleはずして以下のコマンドを実行
func extensions install --package Microsoft.Azure.WebJobs.Extensions.WebPubSub --version 1.0.0
このあとSignalRとCosmosDBのextension入れないとな
SignalRの拡張はこれ
最新の1.6.0をインスト
CosmosDBはこちら
3.0.10をインスト
なぜかcsprojの形式にしたとたん、
本番環境で動かなくなった
すべてのAPIは404になる、なぜだ
結果、csprojに含まれている拡張機能をciのときにビルドできていないのが原因だった。
actionsのymlを書き換えてインストール処理を施したところ、無事200を返すようになったとさ
これはハマりポイントだな......
今日作ったのは汚いciになってしまったけど
yarn startのときに」拡張機能のインストを行うことでもっときれいになりそう
いや~~~~動いてよかった
Web Clientの開発をしている中で、
なぜかWebSocketに接続することは可能だが
受信することができない問題に気が付いた
なんかSIgnalRのときもあったな~と思いつつ、
前にやった方法だと解決できんかった(name:$returnにするやつ)
Azure Functionsランタイムのバージョンをv3にしても
return式&contex.bindings式でダメだった
ちなみにランタイムバージョンを下げるには構成から
AZURE_EXTENSION_VERSIONを~3にすればよいっぽい(知見
これによりWebSocketにbroadcastしたところ、クライアントで通知されたのを確認した
なのでFunctionsで詰まってるだけっぽい
Azure Functions側のバグに構っている余裕はないので
とりあえずWeb PubSub単体でUnityとリアルタイム通信するようにしてみる
Azure.Messaging.WebPubSub1.0.0をnuget installして
UnityにインポートしてIL2CPPビルドしたところ、いい感じに動作した
WebSOcket.Clientは依存パッケージのバージョンが違って
そうするとdllの2重インポートはできないので詰みました
こういう時どうすればいいんだろうな......
とりあえずここでいったん中断
次はwsでsendToAllしたり、それをreceiveAsyncしてみたり
試してみる
リポジトリはこちら
C#の生のClientWebSocket使うとReceiveAsync使ってイベントハンドラを自作するのがすごいめんどくさいので
ここを参考にする
そういえば、@azure/web-pubsub
を使ってブラウザクライアントでsendToAllとか仕様と思ったけど
ブラウザでエラーが出てしまった
Web用ではなかったっぽい
Web PubSubでのデータ送受信をIL2CPPビルドした実機でも確認できた
なぜかかなりSendToAllAsyncで詰まってしまったが、
色々やってみたらうまくいったようだ
Webクライアントでも受信していることを確認した
SendToAllでstringを渡してContentTypeをtextにすればよいと思っていたが
なぜか空のデータだけが渡されていて
Unityだとなぜか受信できずにいた
sendtoallにRequestContent.Createから生成したものを渡すことにした
Create()に文字列を渡すと、なんか変な感じになったり
objectを渡すと、エディタでは成功するけど実機だとダメだったり
2022/01/06 02:46:01.350 10779 10797 Error Unity ExecutionEngineException: Attempting to call method 'System.Text.Json.JsonPropertyInfoNotNullable`4[[<>f__AnonymousType0`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]::.ctor' for which no ahead of time (AOT) code was generated.
最終的に、RequestContent.Crateにobjectを渡し、
第2引数に独自実装のObjectSerializerを渡す頃にした
なぜそうしたかというと、実機ではSystem.Text.Jsonが悪さを指定そうだったので
こいつではなくJsonUtiltliyを使うようにした