如何用SignalR实现类似Cryptocompare的行情数据流式推送?
行情数据流式推送实现咨询
需求背景
要为TradingView图表实现类似Cryptocompare的行情数据流式推送,支持的订阅流格式包括:
- 交易流(Trade):
0~{exchange}~{base}~{quote} - 行情Ticker流:
2~{exchange}~{base}~{quote} - K线周期流:
24~{exchange or CCCAGG}~{base}~{quote}~{period} - 其他类型流
现有SignalR实现及疑问
我用SignalR实现了一个雏形,但不确定实现方式是否正确,后端C#代码如下:
public class MarketData : Hub { public async Task SendMessage(object message) { // 处理接收的消息 var receivedData = JsonConvert.DeserializeObject<dynamic>(message.ToString()); if (receivedData.action == "SubAdd") { // 开始推送数据(示例逻辑,需替换为实际业务) while (true) { var randomData = GenerateRandomData(); await Clients.Caller.SendAsync("ReceiveMessage", randomData); await Task.Delay(1000); // 每秒推送一次示例数据 } } } private string GenerateRandomData() { // 替换为实际数据生成/获取逻辑 return "Random Data: " + new Random().Next(1000).ToString(); } }
配套的测试前端代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>SignalR Client Test</title> <!-- 引入SignalR客户端库 --> <script src="https://cdn.jsdelivr.net/npm/@microsoft/signalr@latest/dist/browser/signalr.min.js"></script> </head> <body> <h1>SignalR Client Test</h1> <button id="connectBtn">Connect</button> <button id="disconnectBtn" disabled>Disconnect</button> <h2>Received Messages:</h2> <ul id="messagesList"></ul> <h2>Send a Custom Message:</h2> <textarea id="customMessage" rows="4" cols="50">{"action":"SubAdd","subs":["0~Binance~BTC~USDT"]}</textarea><br> <button id="sendCustomBtn">Send Custom Message</button> <script> let connection = new signalR.HubConnectionBuilder() .withUrl("https://localhost:5001/hub") .configureLogging(signalR.LogLevel.Information) .build(); const connectBtn = document.getElementById("connectBtn"); const disconnectBtn = document.getElementById("disconnectBtn"); const messagesList = document.getElementById("messagesList"); const sendCustomBtn = document.getElementById("sendCustomBtn"); connectBtn.addEventListener("click", function () { connection .start() .then(function () { console.log("connected"); connectBtn.disabled = true; disconnectBtn.disabled = false; }) .catch((err) => console.error(err.toString())); }); disconnectBtn.addEventListener("click", function () { connection.stop().then(function () { connectBtn.disabled = false; disconnectBtn.disabled = true; }); }); sendCustomBtn.addEventListener("click", function() { const customMessageText = document.getElementById("customMessage").value; let customMessage; try { customMessage = JSON.parse(customMessageText); connection.invoke("SendMessage", customMessage).catch(err => console.error(err.toString())); } catch (error) { console.error("Invalid JSON message:", error); alert("Please enter a valid JSON message."); } }); connection.on("ReceiveMessage", function (message) { let li = document.createElement("li"); li.textContent = message; messagesList.appendChild(li); }); </script> </body> </html>
Orleans Grain实现咨询
我认为Microsoft Orleans Grain适合这个场景:当多个用户订阅同一交易对/交易所时,可以复用Grain实例,还能实现节点负载均衡。想请教该场景下的正确实现方式。
内容的提问来源于stack exchange,提问作者nop
相关产品推荐
相关产品推荐

