1

我使用的是一个相当有限的嵌入式系统,所以我不能使用任何库,我自己构建 HTTP 请求。我可以通过轮询很好地处理统计信息,但我正在尝试打开 Rest Streaming

Nest 站点将您定向到 Firebase 站点,该站点将您定向到 W3C 站点,而我所经历的一切就是“在您的请求中包含标头:接受:文本/事件流”。

如果我发送请求(重定向后):

GET /?auth=[auth code] HTTP/1.1
Host: firebase-apiserver02-tah01-iad01.dapi.production.nest.com:9553

我得到了 JSON 的完整结构。如果我发送:

GET /?auth=[auth code] HTTP/1.1
Host: firebase-apiserver02-tah01-iad01.dapi.production.nest.com:9553
Accept: text/event-stream
Connection: keep-alive

我得到 200 OK 响应,但没有别的。连接没有关闭,但之后什么也没有。我在正确的轨道上吗?看起来这应该是一个更大的交易,这一定是因为我什么都没有,也不知道下一步该去哪里。

有人使用带有 Nest 的 Rest Streaming(没有库)吗?

4

2 回答 2

1

套接字保持活动状态,并通过它发送任何更新。它会返回 200 OK 开始的整个数据,然后在发生更新时不断向您发送更新。这是一个 curl 的例子。需要注意的一件事是,如果您更新恒温器的状态(通过网络或物理方式),您将获得更新。

< HTTP/1.1 200 OK
< Content-Type: text/event-stream; charset=UTF-8
< Access-Control-Allow-Origin: *
< Cache-Control: private, no-cache, max-age=0
<
event: put
data: {"path":"/","data":{"devices":{...}}

event: keep-alive
data: null

...

希望有帮助

于 2014-07-28T19:01:35.613 回答
1

audiotech,看起来nest-firebase 正在使用WebSockets 将更新发送回客户端。我正在使用 C# WindowsForms,但我发现的内容对您有用。

我可以使用以下方法获取我的结构信息:

    HttpWebRequest myStructHttpWebRequest=(HttpWebRequest)WebRequest.Create("https://developer-api.nest.com/structures/?auth=" + AccessToken);
myStructHttpWebRequest.Method = "GET";
myStructHttpWebRequest.MaximumAutomaticRedirections=3;
myStructHttpWebRequest.AllowAutoRedirect=true;
myStructHttpWebRequest.Accept = "text/event-stream; application/json";
myStructHttpWebRequest.Credentials = CredentialCache.DefaultCredentials;
myStructHttpWebRequest.KeepAlive = false;
using(HttpWebResponse myHttpWebResponse = (HttpWebResponse) myStructHttpWebRequest.GetResponseAsync())
{
    if (null != myHttpWebResponse)
    {
        // Store the response.
        Stream sData = myHttpWebResponse.GetResponseStream(); 
        StreamReader readStream = new StreamReader (sData, Encoding.UTF8);
        string data = readStream.ReadToEnd();
        readStream.Close();
        Debug.WriteLine("Response Structure stream received: " + data);
        success = deserializeStructure(data);
    }
}

我将上面的代码更改为: myStructHttpWebRequest.AllowAutoRedirect=false; 并获得了重定向地址路径:

if (HttpStatusCode.TemporaryRedirect == myHttpWebResponse.StatusCode)
{
    string[] redirect = myHttpWebResponse.Headers.GetValues("Location");
    path = redirect[0];
}

我使用此函数启动到此新路径的 Web 套接字连接,并从 firebase 服务器接收此消息:"{\"t\":\"c\",\"d\":{\"t\": \"h\",\"d\":{\"ts\":1406745104997,\"v\":\"5\",\"h\":\"firebase-apiserver01-tah01-i​​ad01.dapi .production.nest.com:9553\",\"s\":\"session-819323581\"}}}"

这是我的 WebSocket 代码:

        private async void startNestWebSocketConnection(string path)
    {
        try
        {
            listener = new ClientWebSocket();
            if (path.StartsWith("https:"))
            {
                path = "wss:" + path.Substring(6) + ":" + COMMUNICATION_PORT.ToString();
            }
            await listener.ConnectAsync(new Uri(path),CancellationToken.None);
            var buffer = new byte[1024 * 4];
            Debug.WriteLine("ClientWebSocket connected " + listener.State.ToString());
            while (true)
            {
                ArraySegment<byte> segment = new ArraySegment<byte>(buffer);

                WebSocketReceiveResult result = await listener.ReceiveAsync(segment, CancellationToken.None);

                if (result.MessageType == WebSocketMessageType.Close)
                {
                    Debug.WriteLine("ClientWebSocket CLOSING");
                    await listener.CloseAsync(WebSocketCloseStatus.InvalidMessageType, "Closing ClientWebSocket", CancellationToken.None);
                    return;
                }

                int count = result.Count;
                while (!result.EndOfMessage)
                {
                    if (count >= buffer.Length)
                    {
                        await listener.CloseAsync(WebSocketCloseStatus.InvalidPayloadData, "That's too long", CancellationToken.None);
                        return;
                    }

                    segment = new ArraySegment<byte>(buffer, count, buffer.Length - count);
                    result = await listener.ReceiveAsync(segment, CancellationToken.None);
                    count += result.Count;
                    Debug.WriteLine("ClientWebSocket getting " + count.ToString());
                }

                string message = Encoding.UTF8.GetString(buffer, 0, count);
                Debug.WriteLine(">" + message);
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine("startNestWebSocketConnection path=" + path + " Exception=" + ex.ToString());
        }
    }

我还不知道回复是什么意思,但它显示了一个时间戳和一个会话 ID!当我做更多测试时,我会告诉你更多。

于 2014-07-30T18:54:49.903 回答