今日は、C#でHTTPのGETアクセスとWebSocketによるデータ取得をやってみようかなと。
GETアクセスには、WebClientを使用。WebSocketには、WebSocket4Net(NuGetからパッケージ取得)を使用した。おまけで、Newtonsoft.Jsonのパッケージも利用している。
HTTPのGETアクセス
ボタンが押されたらWebClientでJSONを取得する。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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を使った。
ソースコードはこんな感じ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
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 + data.@params.message + Environment.NewLine + "----------------------------" + Environment.NewLine + textBox1.Text; })); } }; websocket.Open(); } |
はまってしまった点は、まずは@paramsがなんなのかというところ(予約語回避の@らしい)。あとは、[email protected]をそのままDebug.WriteLineしようとするとエラーが出るところ・・・。
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: ‘条件付き属性があるため、メソッド ‘WriteLine’ を動的に呼び出すことはできません’
これが何を表しているのか、よくわからないけど、動的オブジェクトに対してWriteLineのメソッドのオーバーライドが合わない感じなんだろうか?
1 2 |
Debug.WriteLine((object)data.@params.message); Debug.WriteLine((string)data.@params.message.ToString()); |
こんな感じにすれば問題なく動くっぽい。