使用SignalR實現比特幣價格實時刷新

ASP.NET SignalR是微軟支持的一個運行在 Dot NET 平臺上的 HTML Websocket 框架。它出現的主要目的是實現服務器主動推送(Push)消息到客戶端頁面,這樣客戶端就沒必要從新發送請求或使用輪詢技術來獲取消息。SignalR提供用於鏈接管理(例如,鏈接和斷開的事件),分組鏈接和受權、發送、監聽等一些簡單易用的API,目前API支持JavaScript和C#兩個平臺,咱們能夠在NuGet上面輕鬆獲取這些SDK。javascript

image

建立一個Startup.cs類在系統啓動時註冊SignalR。html

using Owin;
using Microsoft.Owin;
[assembly: OwinStartup(typeof(SignalRDemo.Startup))]
namespace SignalRDemo
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

Hub提供與ASP.NET SignalR通訊的鏈接,使您能夠從一臺服務器鏈接客戶端,並從客戶端到服務器進行遠程過程調用(RPC)。在服務器代碼中,你定義能夠被客戶端調用方法,並調用該客戶端上運行的方法。在客戶端代碼中,你定義能夠從服務器上調用的方法,而且調用服務器上運行的方法。java

實現比特幣價格實時刷新,則只須要服務器到客戶端的調用,我在下述StockHub中,開了一個Timer,每間隔9s去OKCoin獲取交易行情,並將數據返回(refresh)給全部用戶(Clients),OKCoin平臺的交易行情API返回格式爲:{"ticker":{"buy":"4003.95","high":"4046.0","last":"4003.95","low":"3857.0","sell":"4007.06","vol":"50344.8216"}},包括了買賣價格、最高、最低、交易量等數據。jquery

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System.IO;
using System.Net;
using System.Threading;

namespace SignalRDemo.Hubs
{
    [HubName("stock")]
    public class StockHub : Hub
    {
        private const string BTC_CNY = "https://www.okcoin.com/api/ticker.do";

        private static Timer _timer;

        static StockHub()
        {
            _timer = new Timer(Refresh, null, 3000, 9000);
        }

        private static void Refresh(object state)
        {
            GlobalHost.ConnectionManager.GetHubContext<StockHub>().Clients.All.refresh(GetData(BTC_CNY).Replace("ticker", "BTC"));
        }

        private static string GetData(string url)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    return reader.ReadToEnd();
                }
            }
        }
    }
}

修改Default.aspx,引入jQuery和SignalR插件,建立一個refresh方法供StockHub回調使用,該方法在接收到到數據後插入表格(爲演示價格變化過程,記錄每一次更新,而不是修改價格)。api

<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
    <!--Script references. -->
    <script src="Scripts/jquery-1.8.2.min.js"></script>
    <script src="Scripts/jquery.signalR-2.0.2.min.js"></script>
    <script src="signalr/hubs"></script>
    <script type="text/javascript">
        $(function () {
            $.connection.stock.client.refresh = function (data) {
                var obj = eval('(' + data + ')');
                var newRow = "<tr><td>" + obj.BTC.last + "</td><td>" + obj.BTC.buy + "</td><td>" + obj.BTC.sell + "</td><td>" + obj.BTC.high + "</td><td>" + obj.BTC.low + "</td><td>" + obj.BTC.vol + "</td></tr>";
                //if ($("#stock tr").length >= 1) {
                //    $("#stock tr:gt(0)").remove();
                //}
                $("#stock tr:last").after(newRow);
            };
            $.connection.hub.start().done();
        });
    </script>
    <table id="stock" style="width: 100%">
        <tr>
            <th>最近成交價</th>
            <th>買一價</th>
            <th>賣一價</th>
            <th>最高</th>
            <th>最低</th>
            <th>成交量</th>
        </tr>
    </table>
</asp:Content>

自此,全部代碼實現完畢,使用很是簡單,CTRL+F5啓動項目,最終效果以下:服務器

image

再來開發一個簡單的WinForm客戶端,實現WinForm客戶端須要引入Microsoft ASP.NET SignalR .NET Client庫。app

image

與JavaScript相似,依據地址聲明一個HubConnection,在由其建立一個Client Hub Proxy,由Proxy註冊refresh時間,供服務端回調。框架

namespace SignalR.Client
{
    public partial class FrmMain2 : Form
    {
        private readonly HubConnection _hubConnection = new HubConnection("http://localhost:2041/signalr");
        private readonly IHubProxy _buildingApiHubProxy;

        public FrmMain2()
        {
            InitializeComponent();
            _buildingApiHubProxy = _hubConnection.CreateHubProxy("stock");
            _buildingApiHubProxy.On("refresh",
                data => this.refresh(data)
            );
            _hubConnection.Start().Wait();
        }

        private void refresh(string data)
        {
            this.lblMessage.Text = data;
        }
    }
}

image

相關文章
相關標籤/搜索