首页 文章

Android和NodeMCU,从服务器接收响应无法正常工作?

提问于
浏览
0

我在 Android 上编写了一个应用程序,它实现了向服务器发送简单的请求(使用 Volley ) . 服务器站在NodeMCU(ESP8266)微控制器上,用 Lua 编写 . 问题是,在发送请求后,应用程序并不总是能够打印响应 . 如果地址是例如“http://www.google.com " it correctly sends request and receive and display response, but if it is the address from the code below - it correctly sends request (the server reacts) but does not (?) receive response (does not display it, displays: "那没用!”) . 您有任何想法,我该如何解决它并能够打印回复?

Android (part responsible for sending requests):

buttonSynchro.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {


        // Instantiate the RequestQueue.
        String url = "http://192.168.1.12/";


        // Request a string response from the provided URL.
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        // Display the first 500 characters of the response string.
                        testTextView.setText("Response is: "+ response.substring(0,500));
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                testTextView.setText("That didn't work!");
            }
        });


        // Add the request to the RequestQueue.
        RequestQueue queue = Volley.newRequestQueue(SettingsActivity.this);
        queue.add(stringRequest);
    }
});

NodeMCU, Lua:

station_cfg={}
station_cfg.ssid="Dom"
station_cfg.pwd="lalala"
wifi.sta.config(station_cfg)
function receive(conn, request)
        print(request)
        print()
        local buf = "";
        buf = buf.."<!doctype html><html>";
        buf = buf.."<h1> ESP8266 Web Server</h1>";
        buf = buf.."</html>";

        conn:send(buf);
        conn:on("sent", function(sck) sck:close() end);     
        collectgarbage();

end

function connection(conn) 
    conn:on("receive", receive) 

end

srv=net.createServer(net.TCP, 30) 
srv:listen(80, connection)

3 回答

  • 2

    nPn的代码适用于某些用户代理(macOS上的Chrome / Firfox / curl / wget),但其他用户代理(macOS和iOS上的Safari,iOS上的Firefox Klar) . 这可能是由于缺少HTTP标头 .

    我建议你坚持我们在https://nodemcu.readthedocs.io/en/latest/en/modules/net/#netsocketsend的文档中的示例 .

    srv = net.createServer(net.TCP)
    
    function receiver(sck, data)
      print(data)
      print()
    
      -- if you're sending back HTML over HTTP you'll want something like this instead
      local response = {"HTTP/1.0 200 OK\r\nServer: NodeMCU on ESP8266\r\nContent-Type: text/html\r\n\r\n"}
    
      response[#response + 1] = "<!doctype html><html>"
      response[#response + 1] = "<h1> ESP8266 Web Server</h1>"
      response[#response + 1] = "</html>"
    
      -- sends and removes the first element from the 'response' table
      local function send(localSocket)
        if #response > 0 then
          localSocket:send(table.remove(response, 1))
        else
          localSocket:close()
          response = nil
        end
      end
    
      -- triggers the send() function again once the first chunk of data was sent
      sck:on("sent", send)
    
      send(sck)
    end
    
    srv:listen(80, function(conn)
      conn:on("receive", receiver)
    end)
    

    此外,您的代码(以及nPn的代码)会假设WiFi不可用 .

    wifi.sta.config(station_cfg) (with auto-connect=true) and wifi.stat.connect是异步的,因此是非阻塞的 - 与许多其他NodeMCU API一样 . 因此,您应该将上述代码放入一个函数中,并且只有在设备连接到AP并获得IP后才能调用它 . 你可以通过例如使用WiFi事件监视器注册 STA_GOT_IP 事件的回调 . 您将找到一个非常详细的启动序列示例,该序列可以监听https://nodemcu.readthedocs.io/en/latest/en/upload/#initlua处的所有WiFi事件 . 对于初学者,你可能想要修剪它并且只听取get-IP .

  • 1

    根据您上面的评论以及显示回溯的link,您的Android应用程序在onResponse()方法中崩溃,因为您要求的子字符串长于实际的字符串长度 .

    您可以通过多种方式解决这个问题,但其中一个方法是将结束索引设置为响应长度的最小值500(我假设您可以在TextView中获取最大值?) . 你可以尝试改变

    testTextView.setText("Response is: "+ response.substring(0,500));
    

    testTextView.setText("Response is: "+ response.substring(0, Math.min(response.length(), n)));
    

    或者您认为更合适的其他任何方式来限制不会导致IndexOutOfBoundsException的响应的长度

    请参阅substring方法here

    public String substring(int beginIndex,int endIndex)返回一个新字符串,该字符串是此字符串的子字符串 . 子字符串从指定的beginIndex开始,并扩展到索引endIndex - 1处的字符 . 因此子字符串的长度为endIndex-beginIndex . 示例:“hamburger”.substring(4,8)返回“敦促”
    “smiles”.substring(1,5)返回“mile”
    参数:beginIndex - 起始索引,包括 . endIndex - 结束索引,独占 . 返回:指定的子字符串 . 抛出:IndexOutOfBoundsException - 如果beginIndex为负数,或者endIndex大于此String对象的长度,或者beginIndex大于endIndex .

  • 0

    我不是Lua专家,但我认为您在发送回复后正在注册"sent"回调 .

    我认为你应该把它移到连接函数中:

    station_cfg={}
    station_cfg.ssid="Dom"
    station_cfg.pwd="lalala"
    wifi.sta.config(station_cfg)
    function receive(conn, request)
            print(request)
            print()
            local buf = "";
            buf = buf.."<!doctype html><html>";
            buf = buf.."<h1> ESP8266 Web Server</h1>";
            buf = buf.."</html>";
            conn:send(buf);  
            collectgarbage();
    
    end
    
    function connection(conn) 
        conn:on("receive", receive) 
        conn:on("sent", function(sck) sck:close() end);   
    end
    
    srv=net.createServer(net.TCP, 30) 
    srv:listen(80, connection)
    

相关问题