TD Ameritrade .NET

问题描述 投票:0回答:1

有人能让TD Ameritrade流媒体API与C#一起工作吗?他们有一些文档和JavaScript例子在这里 https:/developer.tdameritrade.com内容流数据。. 我已经得到了JavaScript的例子,以工作在 https:/js.do但在.NET中却不能得到任何类似的工作。这是我要做的事情的简写版本。我不能包括我发送的确切内容,因为我试图发送包括账户信息的登录消息,但我可以说我复制并粘贴了在我的JavaScript测试中工作的确切JSON消息到这个例子中的LoginJSON.txt文件中。在这个例子中,只要我发送消息,套接字就会关闭,根本没有文本响应。然而,如果我发送一个故意格式化错误的消息,我实际上会得到文本响应说消息是格式化错误,然后得到一个套接字断开。他们的支持一直没有响应,我理解为是正常的。这里有一些python的例子 https:/www.youtube.comchannelUCBsTB02yO0QGwtlfiv5m25Q但我看了所有的教程,却没有学到任何东西来帮助我让我的代码工作。

        ClientWebSocket socket = new ClientWebSocket();
        var connectAsync = socket.ConnectAsync(new Uri("wss://streamer-ws.tdameritrade.com/ws"), CancellationToken.None);
        string loginRequest;
        using (StreamReader re = new StreamReader("LoginJSON.txt")) {
            loginRequest = re.ReadToEnd();
        }

        connectAsync.Wait();

        Thread readThread = new Thread(
            delegate(object obj)
            {
                while (true) {
                    if (socket.State == WebSocketState.Open) {
                        Console.Out.WriteLine("Waiting");
                        byte[] recBytes = new byte[1024];
                        var clientBuffer = new ArraySegment<byte>(recBytes);
                        var receiveAsync = socket.ReceiveAsync(clientBuffer, CancellationToken.None);
                        receiveAsync.Wait();
                        switch (receiveAsync.Result.MessageType) {
                            case WebSocketMessageType.Text:
                                var s = Encoding.UTF8.GetString(recBytes);
                                Console.Out.WriteLine(s.Trim());
                                break;
                            case WebSocketMessageType.Close:
                                Console.Out.WriteLine("Close message received");
                                break;
                            default:
                                throw new ArgumentOutOfRangeException();
                        }
                    }
                }
            });

        readThread.Start();
        socket.SendAsync(Encoding.UTF8.GetBytes(loginRequest), WebSocketMessageType.Text, true, CancellationToken.None);
        Console.ReadLine();
c# websocket streaming stock ameritrade
1个回答
0
投票

我尝试了WebSocketClient的方法,但从来没有得到很好的工作。我得到的错误和你得到的完全一样。没错,我发现WebSocketClient实际上是一个很好的方法。我发现WebSocketClient实际上使在javascript中实现的非常简单的东西变得复杂化。只需让您的C#调用一个javascript函数来执行javascript并将响应发送回给您。我已经在一个Blazor应用程序中使用C#以这种方式工作,而且工作得天衣无缝。


0
投票

我遇到了同样的问题,我设法解决了它。在我的情况下,时间戳没有正确准备,有必要计算时间戳以获得TokenTimestamp属性,这应该被转换为通用时间。对不起,我的英语从谷歌翻译。) 这里是正确的代码。

DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTime tokenDate = Convert.ToDateTime(userPrincipal.StreamerInfo.TokenTimestamp);
TimeSpan tokenEpoch = tokenDate.ToUniversalTime() - epoch;
long timestamp = (long)Math.Floor(tokenEpoch.TotalMilliseconds);

var credentials = new Credentials
{
    userid = userPrincipal.Accounts[0].AccountId,
    token = userPrincipal.StreamerInfo.Token,
    company = userPrincipal.Accounts[0].Company,
    segment = userPrincipal.Accounts[0].Segment,
    cddomain = userPrincipal.Accounts[0].AccountCdDomainId,
    usergroup = userPrincipal.StreamerInfo.UserGroup,
    accesslevel = userPrincipal.StreamerInfo.AccessLevel,
    authorized = "Y",
    timestamp = timestamp,
    appid = userPrincipal.StreamerInfo.AppId,
    acl = userPrincipal.StreamerInfo.Acl
};
var credentialArr = credentials.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public).Select(p => new KeyValuePair<string, string>(p.Name, p.GetValue(credentials, null).ToString()));
var loginRequest = new Request
{
    service = "ADMIN",
    command = "LOGIN",
    requestid = "0",
    account = userPrincipal.Accounts[0].AccountId,
    source = userPrincipal.StreamerInfo.AppId,
    parameters = new Parameters
    {
        credential = string.Join("&", credentialArr.Where(c => !string.IsNullOrWhiteSpace(c.Value)).Select(c => string.Format("{0}={1}", HttpUtility.UrlEncode(c.Key, Encoding.UTF8), HttpUtility.UrlEncode(c.Value, Encoding.UTF8)))),
        token = userPrincipal.StreamerInfo.Token,
        version = "1.0",
        qoslevel = "0"
    }
};
var req = JsonConvert.SerializeObject(Requests.ToRequests(loginRequest), Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
socketClient = new WebSocket(string.Format("wss://{0}/ws", userPrincipal.StreamerInfo.StreamerSocketUrl));
if(Environment.OSVersion.Version.Major > 5)
{
    socketClient.SslConfiguration.EnabledSslProtocols = (System.Security.Authentication.SslProtocols)3072;
    socketClient.SslConfiguration.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
}
socketClient.Connect();
socketClient.Send(req);
© www.soinside.com 2019 - 2024. All rights reserved.