Подтвердить что ты не робот

Запросы Socket.io POST от Socket.IO-Client-Swift

Я запускаю socket.io на сервере Apache через Python Flask. Мы интегрируем его в приложение iOS (используя библиотеку Socket.IO-Client-Swift), и у нас возникла странная проблема.

Из кода на стороне клиента в приложении (написанного в Swift) я могу просмотреть фактический журнал соединений (клиентская сторона в XCode) и посмотреть соединение, установленное с IP-адреса клиента и выполняемых запросов. Клиент никогда не получает обратно информацию (или любую информацию обратно, даже при использовании глобального обработчика событий событий) с сервера сокетов.

Я написал очень простой тест script в Javascript на HTML-странице и отправил запросы таким образом и получил правильные ответы. С учетом сказанного, похоже, это проблема с iOS. Я нашел эти статьи (но ни один из них не помог устранить проблему):

https://github.com/nuclearace/Socket.IO-Client-Swift/issues/95 https://github.com/socketio/socket.io-client-swift/issues/359

Моя следующая мысль состоит в том, чтобы расширить регистрацию socket.io, чтобы узнать, какие именно данные отправляются в пространство имен сокетов. Есть ли способ зарегистрировать точно, какие данные поступают на сервер (помните, что крюк 'on' на стороне сервера, который я настроил, не получает никаких данных, я пытался зарегистрировать его там, но он, кажется, даже не заходит так далеко).

Я нашел mod_dumpio для Linux, чтобы регистрировать все запросы POST, но я не уверен, насколько хорошо он будет играть с многопоточными и серверами сокетов.

Любые идеи о том, как получать точные данные, чтобы мы могли, по крайней мере, устранить синтаксис и убедиться, что данные не искажаются при отправке на сервер?

Спасибо!

Update

При локальном тестировании мы получили его работу (это был параметр в коде Swift, где пространство имен не было объявлено должным образом). Теперь это нормально работает на localhost, но при выпуске на сервер Apache возникают те же проблемы.

Мы не используем mod_wsgi (насколько я знаю, я относительно новичок в mod_wsgi, извинения за незнание). Раньше мы использовали файл .wsgi, который вызывал основное приложение script, но мы должны были его изменить, потому что mod_wsgi несовместим с Flask SocketIO (как указано в разделе веб-сервера uWSGI здесь). Теперь я запускаю script, используя supervisord, чтобы запустить .py файл как daemon (используя это специально, чтобы он автоматически запускался в случае сбоя сервера).

Локально, он отлично работал, как только мы установили модуль eventlet через pip. Когда я запускал pip freeze в своей виртуальной среде на сервере, был установлен eventlet. Я удалил и переустановил его, чтобы убедиться, что это что-то прояснилось, и ничего не сделал. Никакие другие модули Python, которые находятся на моей локальной копии, по-видимому, не будут влиять на это.

Еще одна вещь, о которой следует помнить, заключается в том, что в функции, инициализирующей приложение, мы меняем порт на порт 80:

socketio.run(app,host='0.0.0.0',port=80)

потому что у нас есть другие функции API, которые проходят через домен, указывающий на сервер в этом приложении. Я не уверен, что это повлияет на что-либо, но это не похоже на локальную версию.

Я снова в тупике и пытаюсь найти что-нибудь, что может помочь. Спасибо за вашу помощь!

Другое обновление

Я не совсем уверен, что происходит, но мы пошли вперед и переписали часть кода, обращая особое внимание на объявления пространства имен в каждой функции сокета event on. Теперь он отлично работает. Когда я получу более подробную информацию, я отправлю их здесь, поскольку я полагаю, что это будет что-то полезное для других, у кого такая же проблема. В этом потоке также есть некоторая действительно ценная информация о том, как идти об отладке/регистрации этих типов проблем, хотя мы никогда не полностью выяснили ответ на исходный вопрос.

4b9b3361

Ответ 1

Используете ли вы флеш-сокету на стороне сервера? Если да, в конструкторе имеется много отладки.

socketio = SocketIO (приложение, async_mode = async_mode, logger = True, engineio_logger = True)

Ответ 2

Я предполагаю, что вы подтвердили, что Apache получает запросы POST. Это должен быть ваш первый тест, если Apache не регистрирует POST-запросы, поступающие из iOS, тогда у вас есть другая проблема.

Если вы получаете запросы POST, вы можете добавить некоторый код в промежуточное программное обеспечение, используемое Flask-SocketIO, и распечатать данные запроса, отправленные Apache mod_wsgi. Это находится в файле flask_socketio/ init.py. Соответствующая часть такова:

class _SocketIOMiddleware(socketio.Middleware):

    # ...

    def __call__(self, environ, start_response):
        # log what you need from environ here
        environ['flask.app'] = self.flask_app
        return super(_SocketIOMiddleware, self).__call__(environ, start_response)

Вы можете узнать, что в environ в спецификации WSGI. В частности, тело запроса доступно в environ['wsgi.input'], которое является файлоподобным объектом, который вы читаете.

Имейте в виду, что после того, как вы прочитаете полезную нагрузку, этот файл будет потреблен, поэтому сервер WSGI не сможет прочитать его снова. Поиск файла обратно в позицию, которая была перед чтением, может работать над некоторыми реализациями WSGI. Более безопасный взлом, который я видел, чтобы избежать этой проблемы, - это прочитать всю полезную нагрузку в буфер, а затем заменить environ['wsgi.input'] на новый StringIO или BytesIO объект.