先日書いた、BitFlyerのwssのサンプル
バッファーをnewしていたのから、ArrayPoolを使う形に変えてみたわけだが・・・
よく考えてみたら、ReceiveAsyncをawaitしている間、ずっとbufferを掴みっぱなしになってしまうわけで、
効率よくshareされない気がした。
そもそも、wssでは、繰り返しバッファーを使うわけだから、このメソッドの中で1つ専用のバッファーを作って、
それを使い続ければ問題なさそうだ。
元のプログラムでは、ループの中でnewしていので、それを外に出すだけで良さそうだ。
それを踏まえて、書き換えたコードが、以下
byte[] buffer = new byte[8192];
const string endpoint = "wss://ws.lightstream.bitflyer.com/json-rpc";
const string message = "{ \"method\" : \"subscribe\" , \"params\" : { \"channel\" : \"lightning_board_FX_BTC_JPY\"} , \"id\":null }";
using var clientWebSocket = new System.Net.WebSockets.ClientWebSocket();
clientWebSocket.Options.KeepAliveInterval = TimeSpan.Zero;
await clientWebSocket.ConnectAsync(new Uri(endpoint), CancellationToken.None);
var messageBytes = Encoding.UTF8.GetBytes(message);
await clientWebSocket.SendAsync(
new ArraySegment<byte>(messageBytes),
System.Net.WebSockets.WebSocketMessageType.Text,
true,
CancellationToken.None);
while (true)
{
if (clientWebSocket.State != System.Net.WebSockets.WebSocketState.Open) { break; }
//Array.Clear(buffer, 0, buffer.Length);
buffer.AsSpan().Clear(); //Spanの方が速かったので変更
var result = await clientWebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
if (result.Count > 0)
{
// buffer , result.Countを使って何かする
}
}
安全のために、Array.Clearを入れているが、Spanを使うとかで、Clearが無くせるともっと良いのだが・・・。
※ AsSpan().Clear()に変更しました。
1件のコメント