如何将Python Websocket实时股票数据传输至C#.NET客户端?
解决方案:Python实时股票数据传输到C#客户端
问题1:Python回调与websockets协程冲突的解决
用线程安全队列桥接SDK的同步回调和websockets的异步协程,避免直接在回调里调用异步方法:
import asyncio import websockets from queue import Queue from your_third_party_sdk import Client # 线程安全队列,存储回调收到的股票数据 msg_queue = Queue() def on_message(message): # 回调里只做入队操作,不处理异步逻辑 msg_queue.put(message) async def forward_to_csharp(): # 单独的协程负责从队列取数据并发送到C#的WebSocket服务 async with websockets.connect("ws://127.0.0.1:8765") as ws: while True: data = msg_queue.get() await ws.send(data) # 初始化SDK并订阅 client = Client() client.subscribe(stock_symbols=["AAPL", "MSFT"]) client.on_message = on_message # 把SDK的运行放到独立线程,避免阻塞协程循环 import threading threading.Thread(target=client.run_forever, daemon=True).start() # 启动协程循环 asyncio.get_event_loop().run_until_complete(forward_to_csharp())
问题2:C#子进程输出停滞的修复
核心原因是Pythonprint默认缓冲输出,C#同步读取会阻塞。以下是两步修复:
1. 让Python输出无缓冲
要么在启动Python时加-u参数强制无缓冲,要么在脚本里手动刷新:
def on_message(message): print(message) import sys sys.stdout.flush() # 每次打印后强制刷新缓冲区
2. C#端异步读取输出
不要用同步ReadToEnd(),改用事件驱动的异步读取:
using System; using System.Diagnostics; class StockDataReceiver { static void Main() { var psi = new ProcessStartInfo { FileName = "python", Arguments = "-u your_stock_script.py", # -u参数开启无缓冲 RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; using (var proc = new Process()) { proc.StartInfo = psi; // 注册输出接收事件 proc.OutputDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) { Console.WriteLine($"实时股价:{e.Data}"); // 这里添加你的业务处理逻辑 } }; proc.Start(); proc.BeginOutputReadLine(); // 启动异步读取 proc.WaitForExit(); } } }
更可靠的替代方案:本地TCP套接字
如果标准输出传输不稳定,直接用本地TCP套接字做数据传输,更适合实时数据流:
Python端代码
import socket from your_third_party_sdk import Client # 连接本地C# TCP服务 tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_socket.connect(("127.0.0.1", 8888)) def on_message(message): # 发送数据,用换行符做分隔 tcp_socket.sendall((message + "\n").encode("utf-8")) # 初始化SDK订阅 client = Client() client.subscribe(stock_symbols=["AAPL", "MSFT"]) client.on_message = on_message # 保持程序运行 import time while True: time.sleep(1)
C#端TCP服务代码
using System; using System.Net; using System.Net.Sockets; using System.Text; class TcpStockServer { static void Main() { var listener = new TcpListener(IPAddress.Loopback, 8888); listener.Start(); Console.WriteLine("等待Python端连接..."); using (var client = listener.AcceptTcpClient()) using (var stream = client.GetStream()) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) { string data = Encoding.UTF8.GetString(buffer, 0, bytesRead).Trim(); Console.WriteLine($"收到股价数据:{data}"); } } listener.Stop(); } }
内容的提问来源于stack exchange,提问作者user2555641
相关产品推荐
相关产品推荐

