在NodeMCU上使用API​​时,只获取部分JSON

时间:2017-12-23 23:15:41

标签: json api http lua nodemcu

我正在使用http.get()从我正在使用的API获取JSON,但它没有获取数据。我怀疑这个JSON对于NodeMCU来说太大了。我只需要子部分“stats:”中的信息。是否只能{J}的http.get()部分?

修改

这是我的代码

function getstats()
http.get("https://api.aeon-pool.com/v1/stats_address?address=WmsGUrXTR7sgKmHEqRNLgPLndWKSvjFXcd4soHnaxVjY3aBWW4kncTrRcBJJgUkeGwcHfzuZABk6XK6qAp8VmSci2AyGHcUit", nil, function(code, pool)
        if (code < 0) then
            print("can't get stats")
        else
            h = cjson.decode(pool)
            hashrate = h[1]["hashrate"]
            print(hashrate)
            dofile('update_display.lua')
        end
    end)
end

我还有另一个函数从getstats()

之上的另一个api获取数据
function getaeonrate()
http.get("https://api.coinmarketcap.com/v1/ticker/aeon/?convert=EUR", nil, function(code, dataaeon)
   if (code < 0) then
      print("can't get aeon")     
   else
      -- Decode JSON data
      m = cjson.decode(dataaeon)
      -- Extract AEON/EUR price from decoded JSON
      aeonrate = string.format("%f", m[1]["price_eur"]);
      aeonchange = "24h " .. m[1]["percent_change_24h"] .. "% 7d " .. m[1]["percent_change_7d"] .. "%"
      dofile('update_display.lua')
      end
  end)
end

但现在奇怪的是,当我想从getstats()访问'pool'时,我从getaeonrate()获取json数据。所以“hashrate”甚至不在json中,因为我从另一个函数获取json。

我尝试仅使用getstats()创建一个新项目,但这根本不起作用我总是得到这样的错误

HTTP client: Disconnected with error: -9
HTTP client: Connection timeout
HTTP client: Connection timeout

昨天我认为api.aeon-pool.com的响应太大了,如果你看看你的webbrowser中的json,你可以看到顶部的条目是'stats:'而我只需要那个,没有其他的东西。所以如果请求是大的那么只有http.get()json的那部分会很好,因此我原来的问题。目前我甚至不确定什么不能正常工作,我读到nodemcu固件通常有http.get()的问题,并且它长时间无法正常工作,但是从api.coinmarketcap获取数据。 com在原始项目中工作正常。

1 个答案:

答案 0 :(得分:0)

HTTP模块的问题几乎与https://github.com/nodemcu/nodemcu-firmware/issues/1707有关(SSL和HTTP存在问题)。

因此,我尝试使用当前主分支上的更多裸骨TLS模块。这意味着您需要手动解析HTTP响应,包括查找JSON内容的所有标头。此外,您似乎使用较旧的NodeMCU版本,因为您仍在使用CJSON - 我在下面使用了SJSON:

当前NodeMCU主分支

function getstats()
  buffer = nil
  counter = 0
  local srv = tls.createConnection()
  srv:on("receive", function(sck, payload)
    print("[stats] received data, " .. string.len(payload))
    if buffer == nil then
      buffer = payload
    else
      buffer = buffer .. payload
    end
    counter = counter + 1

    -- not getting HTTP content-length header back -> poor man's checking for complete response
    if counter == 2 then
      print("[stats] done, processing payload")
      local beginJsonString = buffer:find("{")
      local jsonString = buffer:sub(beginJsonString)
      local hashrate = sjson.decode(jsonString)["stats"]["hashrate"]
      print("[stats] hashrate from aeon-pool.com: " .. hashrate)
    end
  end)
  srv:on("connection", function(sck, c)
    sck:send("GET /v1/stats_address?address=WmsGUrXTR7sgKmHEqRNLgPLndWKSvjFXcd4soHnaxVjY3aBWW4kncTrRcBJJgUkeGwcHfzuZABk6XK6qAp8VmSci2AyGHcUit HTTP/1.1\r\nHost: api.aeon-pool.com\r\nConnection: close\r\nAccept: */*\r\n\r\n")
  end)
  srv:connect(443, "api.aeon-pool.com")
end

请注意,每个网络框架都会触发receive事件:https://nodemcu.readthedocs.io/en/latest/en/modules/net/#netsocketon

由于TLS握手失败,NodeMCU无法与api.coinmarketcap.com建立连接。不知道为什么会这样。否则,您的getaeonrate()也可以同样实施。

冻结1.5.4分支

使用旧分支,网络模块可以连接到coinmarketcap.com。

function getaeonrate()
  local srv = net.createConnection(net.TCP, 1)
  srv:on("receive", function(sck, payload)
    print("[aeon rate] received data, " .. string.len(payload))
    local beginJsonString = payload:find("%[")
    local jsonString = payload:sub(beginJsonString)
    local json = cjson.decode(jsonString)
    local aeonrate = string.format("%f", json[1]["price_eur"]);
    local aeonchange = "24h " .. json[1]["percent_change_24h"] .. "% 7d " .. json[1]["percent_change_7d"] .. "%"
    print("[aeon rate] aeonrate from coinmarketcap.com: " .. aeonrate)
    print("[aeon rate] aeonchange from coinmarketcap.com: " .. aeonchange)
  end)
  srv:on("connection", function(sck, c)
    sck:send("GET /v1/ticker/aeon/?convert=EUR HTTP/1.1\r\nHost: api.coinmarketcap.com\r\nConnection: close\r\nAccept: */*\r\n\r\n")
  end)
  srv:connect(443, "api.coinmarketcap.com")
end

<强>结论

  • 由于固件中的错误(1707),HTTP模块和TLS似乎不适用于您的API。
  • 当前主分支的net / TLS模块设法连接到api.aeon-pool.com但不能连接到api.coinmarketcap.com。
  • 旧的和冷冻的1.5.4分支完全相反。
  • 固件和API提供商之间的密码套装可能也存在问题。

- &GT; :(没有那样的乐趣