今日は、C#でHTTPのGETアクセスとWebSocketによるデータ取得をやってみようかなと。
GETアクセスには、WebClientを使用。WebSocketには、WebSocket4Net(NuGetからパッケージ取得)を使用した。おまけで、Newtonsoft.Jsonのパッケージも利用している。
HTTPのGETアクセス
ボタンが押されたらWebClientでJSONを取得する。
private void button1_Click(object sender, EventArgs e)
{
var webClient = new WebClient();
var stopwatch = new Stopwatch();
stopwatch.Start();
webClient.DownloadStringAsync( new Uri("https://api.bitflyer.jp//v1/getticker?product_code=BTC_JPY") );
webClient.DownloadStringCompleted += ( s1, e1 ) =>
{
stopwatch.Stop();
textBox1.Text = DateTime.Now + Environment.NewLine + e1.Result + Environment.NewLine + string.Format("{0} ms", stopwatch.ElapsedMilliseconds ) + Environment.NewLine + "----------------------------" + Environment.NewLine + textBox1.Text;
};
}
1回目のアクセスは時間かかるが2回目からは速い。

Environment.NewLineというのはWindowsだとCRLFになるようだ。最初、”\n”とか書いて改行されないので少々焦ったところだった。
WebSocket
C#のデフォルトのWebSocketは使いにくいらしく、WebSocket4Netというパッケージにした。C#のJSONも同様に使いにくいのだろうか?ということでNewtonsoft.Jsonを使った。
ソースコードはこんな感じ。
private void button2_Click(object sender, EventArgs e)
{
var channelName = "lightning_board_snapshot_BTC_JPY";
var websocket = new WebSocket("wss://ws.lightstream.bitflyer.com/json-rpc", sslProtocols: SslProtocols.Tls12);
websocket.Opened += (s1, e1) =>
{
websocket.Send(
JsonConvert.SerializeObject(
new
{
method = "subscribe",
@params = new { channel = channelName },
id = 256,
}
)
);
};
websocket.MessageReceived += (s1, e1) =>
{
dynamic data = JObject.Parse(e1.Message);
if (data.id == 256)
{
Debug.WriteLine("subscribed!");
}
if (data.@params != null)
{
this.BeginInvoke((Action)(() => { textBox1.Text = DateTime.Now + Environment.NewLine + [email protected] + Environment.NewLine + "----------------------------" + Environment.NewLine + textBox1.Text; }));
}
};
websocket.Open();
}

はまってしまった点は、まずは@paramsがなんなのかというところ(予約語回避の@らしい)。あとは、[email protected]をそのままDebug.WriteLineしようとするとエラーが出るところ・・・。
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: ‘条件付き属性があるため、メソッド ‘WriteLine’ を動的に呼び出すことはできません’
これが何を表しているのか、よくわからないけど、動的オブジェクトに対してWriteLineのメソッドのオーバーライドが合わない感じなんだろうか?
Debug.WriteLine((object)[email protected]); Debug.WriteLine((string)[email protected]());
こんな感じにすれば問題なく動くっぽい。

