関連
https://www.notion.so/Flutter-x-golang-x-gRPC-f299ddde01bf48bc87ed07d2f4396061
アップロードよりも単純。gRPC ばんざい
schema
service PlayerService {
rpc Download (DownloadRequest) returns (stream DownloadResponse) {}
}
message DownloadRequest {
int64 audio_id = 1;
}
message DownloadResponse {
util.File file = 1;
}
server
func (a *PlayerAdapter) Download(r *playerpb.DownloadRequest, stream playerpb.PlayerService_DownloadServer) error {
ctx := stream.Context()
audio, err := a.audioUC.Get(ctx, r.AudioId)
if err != nil {
return err
}
f, err := os.Open(audio.Path)
if err != nil {
return err
}
defer f.Close()
// バイト単位で分割してストリーミング(要調整)
var b [4096 * 1000]byte
for {
n, err := f.Read(b[:])
if err != nil {
if err != io.EOF {
return err
}
break
}
err = stream.Send(&playerpb.DownloadResponse{
File: &utilpb.File{
Content: b[:n],
},
})
if err != nil {
return err
}
}
util.LoggingInfo(ctx, "PlayerAdapter.Download end", logrus.Fields{
"r.AudioId": r.AudioId,
})
return nil
}
client
@override
Future<Uint8List> download(int id) async {
final channel = createChannel();
final stub = _createStub(channel);
final request = $pbgrpc.DownloadRequest()
..audioId = $fixnum.Int64(id);
var results = <int>[];
// 結果を全て待つ場合, await for で
await for (final reply in stub.download(request)) {
results = [...results, ...reply.file.content];
}
return Uint8List.fromList(results);
}