我想制作一个Web应用程序,以显示来自自定义设备网格的实时传感器数据。我对Dash Python框架很熟悉,因此我决定这次也要使用它。其中一台设备与W5500防护板通信,这是启动的基础。
不幸的是,当我尝试在python中将Dash与BSD套接字融合时,在Linux(Ubuntu 18.04)或Windows 10上都出现了奇怪的行为。
在打开套接字的情况下运行任何Dash应用程序时,尽管我明确使用了不同的接口(interface)和/或端口,但我仍然错误地声明端口/地址对在仍处于打开状态时会被重用(Linux上为errno 98或WinError 10048)-Dash应用程序托管于localhost端口8050,我将分配的IP和其他端口用于套接字。我使用_thread数据包尝试了不同的方法,但是仍然出现相同的错误。
我也知道在此示例中我不接受连接,但是就绑定(bind)/监听不起作用而言,我没有将其放在此处。
如果我在单独的线程中提供该应用程序,则其中之一不会以任何方式响应,因此我不提供任何应用程序或没有收到任何数据。我将附加经过修改的Dash教程示例代码,以显示该问题。
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import socket
import _thread
import atexit
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
print('socet created')
PORT = 9001
IP_ADDR = '192.168.0.38'
s.bind((IP_ADDR, PORT))
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
dcc.Input(id='my-id', value='initial value', type='text'),
html.Div(id='my-div')
])
@app.callback(
Output(component_id='my-div', component_property='children'),
[Input(component_id='my-id', component_property='value')]
)
def update_output_div(input_value):
return 'You\'ve entered "{}"'.format(input_value)
def on_close():
global s
print('port closed')
s.close()
def get_data(dummy):
while True:
data, addr = s.recvfrom(1024)
print('received: ' + str(list(data)))
def run_app(dummy):
app.run_server(debug=True)
#while True:
# pass
if __name__ == '__main__':
atexit.register(on_close)
_thread.start_new_thread( get_data, ('data',))
#_thread.start_new_thread( run_app, ('app',) )
app.run_server(debug=True, host = '127.0.0.1')
while True:
pass
我真正想要的只是在开始时保持简单,并修改感兴趣的值列表,然后每隔n毫秒将它们绘制在实时图形上(无论它们是否已更新)。
如果有人设法将Dash与套接字一起使用,请提供一些帮助或提示如何建立TCP套接字监听。
最佳答案
您可以尝试如下操作:
app.layout = html.Div([
dcc.Input(id='my-id', value='initial value', type='text'),
html.Div(id='my-div'),
html.Div(id='my-hidden-div', style='hidden')
])
@app.callback(
[Output(component_id='my-div', component_property='children'),
Output(component_id='my-hidden-div', component_property='children')
[State(component_id='my-hidden-div', component_property='children')]
)
def get_data(dummy):
while True:
data, addr = s.recvfrom(1024, timeout=0.1)
print('received: ' + str(list(data)))
return str(list(data)), str(list(data))
在这种情况下,只要更改my-hidden-div,就会触发get_data回调。
recvfrom在100毫秒后超时,然后将一个值返回给my-hidden-div,然后该my-hidden-div调用get_data回调。
我不知道这是否行得通。
关于python - 结合使用Dash和套接字API,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54356584/