Отправка сообщений через безопасные (SSL) WebSockets из Python в Python - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть приложение на C ++, в которое встроен скрипт Python. Приложение C ++ отправляет cv::Mat изображений в сценарий Py, который, в свою очередь, выполняет некоторое распознавание изображений (через CNN). Основная идея может быть найдена в моя суть .

Затем мой скрипт на Python хочет отправить результаты предсказания CNN в другое приложение (в Unity, я считаю) через безопасные веб-сокеты с SSL.

У меня нет доступа к настоящему приложению Unity на данный момент, поэтому я должен проверить фактическую часть "отправки", используя простое приложение на сервере Python.

У меня нет большого опыта (или знаний) с сокетами и SSL в Python, поэтому я надеюсь на некоторую помощь.

Все работает, если я просто использую незащищенное HTTP-соединение, но когда я пытаюсь ввести HTTPS и SSL, у меня возникают проблемы.

СТОРОНА СЕРВЕРА:

В последней попытке я использовал следующий серверный скрипт (взятый из здесь ):

import asyncio
import pathlib
import ssl
import websockets

async def hello(websocket, path):
    name = await websocket.recv()
    print(f"< {name}")

    ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
    ssl_context.load_cert_chain(
        pathlib.Path(__file__).with_name('cert.pem'), 
        pathlib.Path(__file__).with_name('key_wopasswd.pem'))

start_server = websockets.serve(hello, 'localhost', 443, ssl=ssl_context)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

Сертификат и файлы ключей были переданы мне коллегой, который отвечает за фактическое получение приложения Unity.

СТОРОНА КЛИЕНТА:

После этого я попытался соединиться и отправить сообщения, например, ( фрагмент 1 ):

import json
import http.client, ssl
import time

ws = None
def send(msg="lol"):
    global ws
    if ws is None:
        ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
        ssl_context.load_cert_chain('cert.pem', 'key_wopasswd.pem')
        ws = http.client.HTTPSConnection("localhost", 443, context=ssl_context)
        ws.connect()
        print("connected successfully!")
    else:
        jsonString = json.dumps({"Time":int(time.time()), "Message":msg})
        ws.send(jsonString.encode('utf-8'))  

В этом случае просто ничего не происходит.

Или вот так ( фрагмент 2 ):

import websocket, ssl
import time

ws = None
def send(msg="lol"):
    global ws
    if ws is None: 
        ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_REQUIRED,
                                         "ssl_version": ssl.PROTOCOL_TLSv1, 
                                         "certfile": "cert.pem", 
                                         "keyfile": "key_wopasswd.pem"})
        ws.connect("wss://localhost:443")        
    else:
        jsonString = json.dumps({"Time":int(time.time()), "Message":msg})        
        ws.send(jsonString.encode('utf-8'))  

В этом случае я получаю следующую ошибку:

Traceback (most recent call last):
  File ".\client2.py", line 21, in send
    ws.connect("wss://localhost:443")
  File "C:\Program Files\Python36\lib\site-packages\websocket\_core.py", line 220, in connect
    options.pop('socket', None))
  File "C:\Program Files\Python36\lib\site-packages\websocket\_http.py", line 126, in connect
    sock = _ssl_socket(sock, options.sslopt, hostname)
  File "C:\Program Files\Python36\lib\site-packages\websocket\_http.py", line 253, in _ssl_socket
    sock = _wrap_sni_socket(sock, sslopt, hostname, check_hostname)
  File "C:\Program Files\Python36\lib\site-packages\websocket\_http.py", line 232, in _wrap_sni_socket
    server_hostname=hostname,
  File "C:\Program Files\Python36\lib\ssl.py", line 401, in wrap_socket
    _context=self, _session=session)
  File "C:\Program Files\Python36\lib\ssl.py", line 808, in __init__
    self.do_handshake()
  File "C:\Program Files\Python36\lib\ssl.py", line 1061, in do_handshake
    self._sslobj.do_handshake()
  File "C:\Program Files\Python36\lib\ssl.py", line 683, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)

Я также попробовал простой http.server.HTTPServer, но единственное отличие заключалось в том, что с первым клиентом ( Фрагмент 1 ) он не печатал сообщения после каждой отправки, а вместо этого накапливал все полученные сообщения. и распечатал их все вместе после того, как я остановил клиента, с ошибкой: код 400, сообщение Синтаксис неправильного запроса .

ТЛ; др По сути, мне нужен хороший пример того, как я могу подключиться к защищенному HTTPS-серверу с помощью SSL один раз, а затем продолжать отправлять строковые сообщения, пока приложение не остановится.

Небольшое обновление:

Это работает, если я пишу клиенту так, но только если я закрываю и открываю соединение после каждого сообщения:

import json
import websocket, ssl
import time

ws = None
def send(msg="..."):
    global ws
    if ws is None:
        ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE,
                                         "ssl_version": ssl.PROTOCOL_TLSv1, 
                                         "certfile": "cert.pem", 
                                         "keyfile": "key_wopasswd.pem"})
        ws.connect("wss://localhost:443")

    jsonString = json.dumps({"Time":int(time.time()), "Message":msg})
    ws.send(jsonString.encode('utf-8'))         
    ws.close()       
    ws = None 

########################
i = 0
while i < 10:
    i = i + 1
    send("i = %d" % i)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...