Python Docker无法识别asyncio_mqtt?

Python Docker无法识别asyncio_mqtt?,python,docker,mqtt,python-asyncio,portainer,Python,Docker,Mqtt,Python Asyncio,Portainer,我目前正在将我的代码转换成docker图像,以基于传感器控制灯光。这方面我是个新手。它在本地运行,但当我使用docker build将其转换为具有此dockerfile的映像时: #set base image (host OS) FROM python:3.8-slim # set the working directory in the container WORKDIR /code # copy the dependencies file to the working directo

我目前正在将我的代码转换成docker图像,以基于传感器控制灯光。这方面我是个新手。它在本地运行,但当我使用docker build将其转换为具有此dockerfile的映像时:

#set base image (host OS)
FROM python:3.8-slim

# set the working directory in the container
WORKDIR /code

# copy the dependencies file to the working 
directory
COPY requirements.txt .

# install dependencies
RUN pip install -r requirements.txt

# copy the content of the local src directory to the working directory
COPY src/ .

# command to run on container start
CMD [ "python", "./main.py"]
我得到以下错误:

Traceback (most recent call last):
File "/usr/local/lib/python3.8/site- 
packages/asyncio_mqtt/client.py", line 79, in 
connect
await loop.run_in_executor(None, 
self._client.connect, self._hostname, self._port, 
60)File 
"/usr/local/lib
/python3.8/concurrent/futures/thread.p y", line 
57, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.8/site- 
packages/paho/mqtt/client.py", line 941, in 
connect
return self.reconnect()
File "/usr/local/lib/python3.8/site- 
packages/paho/mqtt/client.py", line 1075, in 
reconnect
sock = self._create_socket_connection()
File "/usr/local/lib/python3.8/site- 
packages/paho/mqtt/client.py", line 3546, in 
_create_socket_connection
return socket.create_connection(addr, 
source_address=source, timeout=self._keepalive)
File "/usr/local/lib/python3.8/socket.py", line 
787, in create_connection
for res in getaddrinfo(host, port, 0, 
SOCK_STREAM):
File "/usr/local/lib/python3.8/socket.py", line 
918, in getaddrinfo
for res in _socket.getaddrinfo(host, port, 
family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not 
known
在处理上述异常期间,发生了另一个异常:

Traceback (most recent call last):
File "./main.py", line 89, in <module>
asyncio.run(main())
File 
"/usr/local/lib/python3.8/asyncio/runners.py", 
line 44, in run
return loop.run_until_complete(main)
File 
"/usr/local/lib/
python3.8/asyncio/base_events.py", line 616, in 
run_until_complete
return future.result()
File "./main.py", line 86, in main
await asyncio.gather(*tasks)
File "./main.py", line 26, in sub_and_listen_task
async with Client(self.broker) as client:
File "/usr/local/lib/python3.8/site- 
packages/asyncio_mqtt/client.py", line 324, in 
__aenter__
await self.connect()
File "/usr/local/lib/python3.8/site- 
packages/asyncio_mqtt/client.py", line 88, in 
connect
raise MqttError(str(error))
asyncio_mqtt.error.MqttError: [Errno -2] Name or  
service not known
连接、发布等代码如下:

class mqtt_task():
    def __init__(self, broker, subscription):
       self.broker = broker
       self.subscription = subscription

    async def sub_and_listen_task(self):
        async with Client(self.broker) as client:
            self.client = client
            async with client.filtered_messages(self.subscription) as 
            messages:
                await client.subscribe(self.subscription)
                async for message in messages:
                    if "ON" in message.payload.decode("utf-8"):
                        space_name = config[0]
                        spaces[space_name].moved()

    async def publish_msg(self, space_name, state):
        msg = {'state': state}
        try:
            await self.client.publish(space_name + '/desired/light' , 
orjson.dumps(msg))
        except AttributeError as ex:
            print('Unable to publish to ' + space_name + 
            '/desired/light')
            #print(ex)
mqtt = mqtt_task(broker_local, subscription_local)
class SpaceCode:

    def __init__(self, name):
        self.name = name
        self.event = asyncio.Event()
        self.task =  asyncio.create_task(self.motion_task())

    def moved(self):
        print('Movement detected...')
        self.event.set()

    async def movement_detected(self): 
        await self.event.wait()
        self.event.clear()

    async def motion_task(self):
        while True:
        await mqtt.publish_msg(self.name, 'on')
        print('TURNING ON.... ' + self.name)
        try:
            await asyncio.wait_for(self.movement_detected(), timeout=time_untill_dim)
            continue
        except asyncio.TimeoutError:
            print('TIMEOUT...DIMMING ' + self.name)
            await mqtt.publish_msg(self.name, 'dim')
        try:
            await asyncio.wait_for(self.movement_detected(), timeout=time_untill_shutoff)
            continue
        except asyncio.TimeoutError:
            print('TIMEOUT...TURNING OFF ' + self.name)
            await mqtt.publish_msg(self.name, 'off')
            await self.movement_detected()

spaces = dict()
    async def main():
        tasks = []
        for name in config:
             spaces[name] = SpaceCode(name)
        tasks.append(mqtt.sub_and_listen_task())
        for t in spaces.values():
            tasks.append(t.task)
        print(tasks)
        await asyncio.gather(*tasks)

if __name__ == "__main__":
     asyncio.run(main())

任何反馈都将不胜感激

@hardillb是对的,错误消息与连接问题有关。代理永远无法连接,因为在docker中,它不在docker中的正确网络中。

您的代码是什么样子的?您如何设置连接信息?@dirn将立即编辑它,因为它对于注释来说太长。问题在于代理主机名的DNS解析。我建议您在尝试连接之前打印出来。@hardillb打印DNS解析?请允许我问一下您是如何做到这一点的,因为我很难从错误消息中识别错误。因为这就是“名称或服务未知”的含义。不幸的是,asyncio_mqtt包掩盖了引发的实际异常,通过查看其源代码(第[88]行)或0.8.1版可以看出这一点
class mqtt_task():
    def __init__(self, broker, subscription):
       self.broker = broker
       self.subscription = subscription

    async def sub_and_listen_task(self):
        async with Client(self.broker) as client:
            self.client = client
            async with client.filtered_messages(self.subscription) as 
            messages:
                await client.subscribe(self.subscription)
                async for message in messages:
                    if "ON" in message.payload.decode("utf-8"):
                        space_name = config[0]
                        spaces[space_name].moved()

    async def publish_msg(self, space_name, state):
        msg = {'state': state}
        try:
            await self.client.publish(space_name + '/desired/light' , 
orjson.dumps(msg))
        except AttributeError as ex:
            print('Unable to publish to ' + space_name + 
            '/desired/light')
            #print(ex)
mqtt = mqtt_task(broker_local, subscription_local)
class SpaceCode:

    def __init__(self, name):
        self.name = name
        self.event = asyncio.Event()
        self.task =  asyncio.create_task(self.motion_task())

    def moved(self):
        print('Movement detected...')
        self.event.set()

    async def movement_detected(self): 
        await self.event.wait()
        self.event.clear()

    async def motion_task(self):
        while True:
        await mqtt.publish_msg(self.name, 'on')
        print('TURNING ON.... ' + self.name)
        try:
            await asyncio.wait_for(self.movement_detected(), timeout=time_untill_dim)
            continue
        except asyncio.TimeoutError:
            print('TIMEOUT...DIMMING ' + self.name)
            await mqtt.publish_msg(self.name, 'dim')
        try:
            await asyncio.wait_for(self.movement_detected(), timeout=time_untill_shutoff)
            continue
        except asyncio.TimeoutError:
            print('TIMEOUT...TURNING OFF ' + self.name)
            await mqtt.publish_msg(self.name, 'off')
            await self.movement_detected()

spaces = dict()
    async def main():
        tasks = []
        for name in config:
             spaces[name] = SpaceCode(name)
        tasks.append(mqtt.sub_and_listen_task())
        for t in spaces.values():
            tasks.append(t.task)
        print(tasks)
        await asyncio.gather(*tasks)

if __name__ == "__main__":
     asyncio.run(main())