Android & NodeMCU, 接收服务器响应无法正常工作?
我已经在 Android 上编写了一个应用程序,可以发送简单的请求(使用 Volley),以发送到服务器。服务器在 NodeMCU(ESP8266)微控制器上运行,使用 Lua 编写。问题是,在发送请求后,应用程序并不总是能够打印响应。如果地址为例如“ http://www.google.com”,它会正确地发送请求并接收和显示响应,但如果是下面的代码中的地址-它会正确地发送请求(服务器会有反应),但不会(?)接收响应(不显示响应,显示:“ That didn ' t work!)。你有什么想法,怎样才能修复它并能够打印响应?
Android(负责发送请求的部分):
buttonSynchro.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 实例化请求队列。
String url = "http://192.168.1.12/";
// 从所提供的 URL 请求字符串响应。
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// 显示响应字符串的前 500 个字符。
testTextView.setText("Response is: "+ response.substring(0,500));
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
testTextView.setText("That didn't work!");
}
});
// 将请求添加到请求队列中。
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)
代码由 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()
-- 如果您要通过 HTTP 发送 HTML,则应改用以下内容
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>"
-- 发送并从 'response' 表中删除第一个元素
local function send(localSocket)
if #response > 0 then
localSocket:send(table.remove(response, 1))
else
localSocket:close()
response = nil
end
end
-- 一旦发送了第一块数据就再次触发 send() 函数
sck:on("sent", send)
send(sck)
end
srv:listen(80, function(conn)
conn:on("receive", receiver)
end)
此外,您的代码(以及 nPn 的代码)对 WiFi 有一些不应该有的假设。
wifi.sta.config(station_cfg)(带有 auto-connect=true)和 wifi.stat.connect 是 _异步_,因此是非阻塞的 - 许多其他 NodeMCU API 也是如此。因此,您应将上述代码放入函数中,并仅在设备连接到 AP 并获得 IP 后调用它一次。您可以通过为 WiFi 事件监视器注册 STA_GOT_IP 事件的回调来实现这一点。您将在https://nodemcu.readthedocs.io/en/latest/en/upload/#initlua中找到一个非常详细的样例启动序列,该序列监听所有 WiFi 事件。对于初学者,您可能需要对其进行简化,并仅监听 got-IP 事件。
根据您上面的评论和您发布的 链接 显示的回溯,您的 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 方法这里
public String substring(int beginIndex, int endIndex)
返回一个新字符串,它是此字符串的子字符串。子字符串从指定的beginIndex开始,一直到索引结尾的endIndex - 1处的字符。因此,子串的长度为endIndex-beginIndex。
示例:
"hamburger".substring(4, 8) 返回 "urge" "smiles".substring(1, 5) 返回 "mile"参数: beginIndex - 字符串的开始索引(包括在内)。 endIndex - 字符串的结束索引(不包括在内)。 返回:指定的子字符串。抛出: IndexOutOfBoundsException - 如果 beginIndex 为负,或endIndex 大于此 String对象的长度,或beginIndex 大于 endIndex。
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

我不是 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)