Я пытаюсь запустить сервер веб-сокетов на Raspberry Pi, который отправляет обратно изображение, когда получает какое-либо сообщение (для тестирования), но мне нужно, чтобы это было в отдельном потоке, чем основной поток. И, как вы можете видеть в конце основного раздела, как только я запускаю «сетевой поток», я запускаю бесконечный цикл с печатью только для того, чтобы доказать, что многопоточность работает.
Это код сервера (ятакже прикрепит код клиента)
from autobahn.asyncio.websocket import WebSocketServerProtocol, WebSocketServerFactory
from pathlib import Path
import asyncio
import threading
from threading import Thread
import time
from apscheduler.schedulers.asyncio import AsyncIOScheduler
class MyServerProtocol(WebSocketServerProtocol):
def onConnect(self, request):
print ('Thread:', threading.currentThread().getName(), "Client connecting: {0}".format(request.peer))
def onOpen(self):
print('Thread:', threading.currentThread().getName(), "WebSocket connection open.")
def onMessage(self, payload, isBinary):
if isBinary:
print( "Binary message received: {0} bytes".format(len(payload)) )
else:
print( "Text message received: {0}".format(payload.decode('utf8')) )
homePath = str(Path.home())
with open(str(homePath + "/Pictures/rafa.jpg"), "rb") as image:
f = image.read()
data = bytearray(f)
self.sendMessage(bytes(data), True)
def onClose(self, wasClean, code, reason):
print('Thread:', threading.currentThread().getName(), "WebSocket connection closed: {0}".format(reason))
def ServerCreate():
print ('Thread:', threading.currentThread().getName(), 'ServerCreate')
#loopNetwork = asyncio.get_event_loop()
loopNetwork = asyncio.new_event_loop()
asyncio.set_event_loop(loopNetwork)
factory = WebSocketServerFactory(u"ws://127.0.0.1:9000")
factory.protocol = MyServerProtocol
coro = loopNetwork.create_server(factory, '0.0.0.0', 9000)
server = loopNetwork.run_until_complete(coro)
try:
loopNetwork.run_forever()
print("loop is finished")
except KeyboardInterrupt:
print ('Thread:', threading.currentThread().getName(), 'KeyboardInterrupt')
pass
finally:
print ('Thread:', threading.currentThread().getName(), 'Finally - Close')
server.close()
loopNetwork.close()
if __name__ == '__main__':
print ('Main Thread name:', threading.currentThread().getName())
networkThread = Thread(target=ServerCreate)
networkThread.isDaemon = True
networkThread.start()
#ServerCreate()
while (True):
print ('Main Thread name:', threading.currentThread().getName(),'MainTrueLoop')
time.sleep(4.0)
Это код клиента
from autobahn.asyncio.websocket import WebSocketClientProtocol, WebSocketClientFactory
import io
from PIL import Image
import asyncio
import threading
from threading import Thread
class MyClientProtocol(WebSocketClientProtocol):
def onConnect(self, response):
print("Server connected: {0}".format(response.peer))
def onConnecting(self, transport_details):
print("Connecting; transport details: {}".format(transport_details))
return None # ask for defaults
def onOpen(self):
print("WebSocket connection open.")
def hello():
self.sendMessage(u"Hello, world!".encode('utf8'))
self.sendMessage(b"\x00\x01\x03\x04", isBinary=True)
self.factory.loop.call_later(1, hello)
# start sending messages every second ..
hello()
def onMessage(self, payload, isBinary):
if isBinary:
#image = Image.open(io.BytesIO(payload))
#image.show()
print("Binary message received: {0} bytes".format(len(payload)))
else:
print("Text message received: {0}".format(payload.decode('utf8')))
def onClose(self, wasClean, code, reason):
print("WebSocket connection closed: {0}".format(reason))
if __name__ == '__main__':
print ('Thread:', threading.currentThread().getName(), 'MainFunction!')
factory = WebSocketClientFactory(u"ws://127.0.0.1:9000")
factory.protocol = MyClientProtocol
loop = asyncio.get_event_loop()
coro = loop.create_connection(factory, '127.0.0.1', 9000)
#coro = loop.create_connection(factory, '192.168.1.99', 9000)
loop.run_until_complete(coro)
loop.run_forever()
print("loop is finished")
loop.close()
Это вывод обеих программ при запуске их
Вывод сервера:
Main Thread name: MainThread
Thread: Thread-1 ServerCreate
Main Thread name: MainThread MainTrueLoop
Thread: Thread-1 Client connecting: tcp4:127.0.0.1:51022
Main Thread name: MainThread MainTrueLoop
Thread: Thread-1 WebSocket connection closed: connection was closed uncleanly (peer dropped the TCP connection without previous WebSocket closing handshake)
Main Thread name: MainThread MainTrueLoop
Main Thread name: MainThread MainTrueLoop
Main Thread name: MainThread MainTrueLoop
Main Thread name: MainThread MainTrueLoop
Main Thread name: MainThread MainTrueLoop
Main Thread name: MainThread MainTrueLoop
Вывод клиента
Thread: MainThread MainFunction!
Connecting; transport details: {"peer": "tcp4:127.0.0.1:9000", "is_secure": false, "secure_channel_id": {}}
dropping connection to peer tcp4:127.0.0.1:9000 with abort=True: WebSocket opening handshake timeout (peer did not finish the opening handshake in time)
WebSocket connection closed: connection was closed uncleanly (WebSocket opening handshake timeout (peer did not finish the opening handshake in time))
Как вы можете видеть, что-то сумасшедшее в том, что на выходе сервера мы видим это: Thread:Соединение с клиентом Thread-1: tcp4: 127.0.0.1: 51022
Несмотря на то, что я специально настраиваю порт на 9000, он говорит 51022, но иногда это другое случайное число, обычно около 50000.
Почему это происходит?