每当变量在服务器端更改其值时,如何使用socket.io将数据发送到客户端?

时间:2019-07-05 16:04:07

标签: javascript node.js socket.io

背景

我正在使用<div class="container"> <svg height="100%" width="100%"> <text onclick="move(evt)" dx="0%" dy="50%" font-size="400">This is my Journey </text> </svg> </container>rpio作为我的应用程序的服务器一起工作,同时我希望能够使用raspberry控制GPIO。到目前为止一切顺利,我只是一个初学者,我只是想在html页面上显示与GPIO相关的信息。

我想做什么

我想根据碰巧在服务器端进行操作的变量在客户端进行动态更改;换句话说,我希望每当此变量在服务器端更改其值时,javascript会将其发送到客户端,以便我可以在{{1}内使用(显示)该变量的更新版本。 } 标签。 就我而言,我只想在页面上显示某个树莓针的高低。我使用一个socket.io函数,该函数具有一个paragraph循环,该循环在每次迭代时都打开和关闭某个引脚。 代码

我正在渲染主页'/',在这里我可以单击一个按钮以将发布请求发送到'/',然后渲染在blinkLed的客户端部分位于的blinkLed页面以及在段落内要显示图钉状态的位置;当此类页面加载时,socketio在服务器端执行功能for,以进行socketio技巧,通过blinkLed()函数将引脚置于高或低状态。一切正常。 注意,在函数rpio中,每次在rpiowrite循环中调用blinkLed()时,我都会使用socket.emit发出字符串“ high”或“ low”。

app.js

rpiowrite

blinkLed.ejs

for

问题

var rpio = require('rpio') var app = require('express')() var http = require('http').createServer(app); var io = require('socket.io')(http); async function blinkLed(socket){ rpio.open(12, rpio.OUTPUT, rpio.LOW); for (var i = 0; i < 5; i++) { /* On for 1 second */ await rpio.write(12, rpio.HIGH); await rpio.sleep(1); await socket.emit('data','high') /* Off for half a second (500ms) */ await rpio.write(12, rpio.LOW); await rpio.msleep(500); await socket.emit('data','low') } } app.set('view engine', 'ejs'); app.get("/", function(req,res){ res.render('home') }) io.on('connection', function(socket){ console.log('Blink Led Page'); blinkLed(socket) }); app.post("/", async function(req,res){ res.render('blinkLed'); }) http.listen(3000,'0.0.0.0',function(){ console.log('server on') }) 函数运行良好;问题在于,自从for循环迭代开始以来就没有显示段落,而是仅在<script src="/socket.io/socket.io.js"></script> <script> function showParagraph(data){ return document.getElementById('p').innerHTML=data } var socket = io(); socket.on('data', function(data){ showParagraph(data) }) </script> <h1>BlinkLed</h1> <p id='p'></p> <a href='/'>Back</a> 迭代结束之后才显示某些内容。看来rpio仅在最后一次迭代后才向客户端发出,然后仅在迭代的最后一个循环结束后才更改段落的值。我想在for循环的每次迭代中听听这些变化。反正有吗?

在此先感谢您提供任何帮助!

编辑:改进的问题

1 个答案:

答案 0 :(得分:1)

您的rpio.write()rpio.sleep()socket.emit()函数不会返回承诺。因此,将await与它们一起使用根本没有用,因为await仅在您等待诺言时才有用。

因此,您的for循环只是一个同步for循环,并且socket.emit()可能实际上无法发送其数据,除非您给nodejs提供一些循环来处理它,这在{之后{1}}循环完成。

for也可能实际上正在发送数据,但是数据以如此之快的速度到达客户端,您将永远没有机会看到屏幕更新,而您看到的只是最终更新

socket.emit()函数阻止node.js Javascript线程。就像在the doc for your rpio libirary中所说的那样:“睡眠功能块,但是很少在这些简单的程序中做这件事。使用setInterval()/ setTimeout()循环代替 如果重要的话。” 嗯,这很重要。

因此,这里的一种解决方案是使用实际的非阻塞延迟,使每个人都有机会实际处理事物:

rpio.sleep()