Советники: Программирование на MQL5 для трейдеров — исходные коды из книги. Часть 7 - страница 3
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Я прилагаю несколько исправлений и улучшений в классах websockets.
В кодовой базе опубликованы исправления и улучшения для чтения экономического календаря и экспорта в CSV. В частности, исправлен алгоритм сортировки для случая преимущественно отсортированных больших массивов (которые обычно получаются из MQL5 calendar API), что позволяет устранить замедления и переполнения стека.
В строке 126 msclient.mqh "return connection.handshake(url, host, origin, custom_headers);" при передаче полного 'url' вместо 'path' возникает ошибка 403 на python websocket. Мне пришлось внести это изменение, чтобы советник смог успешно подключиться к моему python websocket серверу.
Яприкрепил журнал сервера от Postman (прошел) и EA до внесения изменений (не прошел)
Но вот следующая проблема, мой сервер автоматически посылает keepalive ping с заданным интервалом, но MT5 websocket не отвечает, и это поведение заставляет сервер всегда терять соединение с клиентом сразу после таймаута ping.
Пожалуйста, любая помощь в отношении keepalive ping pong будет оценена по достоинству.
В строке 126 msclient.mqh есть небольшой бутон "return connection.handshake(url, host, origin, custom_headers);", передача полного 'url' вместо 'path' приводит к ошибке 403 на python websocket. Мне пришлось внести это изменение, чтобы советник смог успешно подключиться к моему python websocket серверу.
Яприкрепил журнал сервера от Postman (прошел) и EA до внесения изменений (не прошел)
Но вот следующая проблема, мой сервер автоматически посылает keepalive ping с заданным интервалом, но MT5 websocket не отвечает, и это поведение заставляет сервер всегда терять соединение с клиентом сразу после таймаута ping.
Пожалуйста, любая помощь в отношении keepalive ping pong будет оценена по достоинству.
Здравствуйте, да, вы можете использовать путь в вызове клиента:
С другой стороны, синтаксис HTTP-запроса поддерживает полный URI в качестве цели, и я проводил тесты с исходными кодами на разных серверах (включая wss://ws.postman-echo.com/raw), и они работали нормально. Так что я не уверен, является ли это нарушением или ваша реализация python в каком-то смысле слишком жесткая.
Что касается ping/pong, то он должен работать. Взгляните на wsprotocol.mqh:
Так что, пожалуйста, отладьте это на вашей стороне, поскольку у вас есть сервер, отправляющий пинги вашему клиенту.
BTW, я забыл добавить новую версию MQL5Book/StringUtils.mqh, используемую в ws/sources.
Проблема находится в строке 310 в переключателе/кейсе фрейма ws ping, когда создается фрейм websocket:
IWebSocketFrame *temp = WebSocketFrame::create(WS_FRAME_OPCODE::WS_PONG_FRAME, frame.getData());
frame.getData() сервер, похоже, подтверждает понг, только если данные пинга основаны на тексте/строке, но терпит неудачу, если был отправлен двоичный пинг
, поэтому мне пришлось использовать перегруженный frame.getData(uchar &buf[]), чтобы заставить его работать в обоих случаях. Не знаю, встретятся ли мне другие варианты использования, которые (мое изменение) сломает, но пока все выглядит нормально.
Просто из любопытства, мне интересно, почему мы должны вручную проверять наличие сообщений с интервалом в обработчике событий OnTimer(), в то время как я вижу что-то, что похоже на функцию обработчика событий OnMessage входящих сообщений. Хотя текущая настройка работает как есть, но я буду признателен, если вы сможете подробнее объяснить, почему именно такой подход
@Stanislav Korotky еще раз спасибо за помощь. Что касается проблемы пинг-понга с сервером python websocket, при дальнейшей отладке я заметил, что сервер посылает запрос на пинг в виде текстовых или бинарных данных, а MT5 успешно отвечает только в том случае, если посылается текстовый пинг. Это помогло мне отследить и устранить проблему.
Проблема находится в строке 310 в переключателе/кейсе фрейма ws ping, когда создается фрейм websocket:
IWebSocketFrame *temp = WebSocketFrame::create(WS_FRAME_OPCODE::WS_PONG_FRAME, frame.getData());
frame.getData() сервер, похоже, подтверждает понг, только если данные пинга основаны на тексте/строке, но терпит неудачу, если был отправлен двоичный пинг
, поэтому мне пришлось использовать перегруженный frame.getData(uchar &buf[]), чтобы заставить его работать в обоих случаях. Не знаю, встретятся ли мне другие варианты использования, которые (мое изменение) сломает, но пока все выглядит нормально.
Просто из любопытства, мне интересно, почему мы должны вручную проверять наличие сообщений с интервалом в обработчике событий OnTimer(), в то время как я вижу что-то, что похоже на функцию обработчика событий OnMessage входящих сообщений. Хотя текущая настройка работает как есть, но я буду признателен, если вы сможете подробнее объяснить, почему именно такой подход
Спасибо за ваши усилия. Я рассмотрю возможность включения ваших правок в исходные коды.
Что касается OnTimer и OnMessage, они предоставлены потому, что вы можете захотеть реализовать различную логику обработки в вашем приложении. Чтение из сокетов блокируется на уровне MQL5 API, с заданным таймаутом. Таким образом, если вас интересует только ожидание новых сообщений, их обработка и автоматическая генерация ответов, вы можете делать это в блокирующем режиме (с бесконечным таймаутом при чтении и без OnTimer) - то есть приложение как бы застыло в ожидании данных. Но если вам нужно обеспечить отзывчивый пользовательский интерфейс (как в случае с чатом), то в OnTimer-обработчике вы устанавливаете небольшой таймаут для коротких попыток чтения (они могут выдать пустые данные, если таймаут истек) и отслеживаете действия пользователя в промежутках между ними.
Спасибо за ваши усилия. Я рассмотрю возможность включения ваших правок в исходные коды.
Что касается OnTimer и OnMessage, то они приведены потому, что вы можете захотеть реализовать различную логику обработки в своем приложении. Чтение из сокетов блокируется на уровне MQL5 API, с заданным таймаутом. Таким образом, если вас интересует только ожидание новых сообщений, их обработка и автоматическая генерация ответов, вы можете делать это в блокирующем режиме (с бесконечным таймаутом при чтении и без OnTimer) - то есть приложение как бы застыло в ожидании данных. Но если вам нужно обеспечить отзывчивый пользовательский интерфейс (как в случае с чатом), то в OnTimer-обработчике вы устанавливаете небольшой таймаут для коротких попыток чтения (они могут выдать пустые данные, если таймаут истек) и отслеживаете действия пользователя в промежутках между ними.
Очередная порция мелких исправлений и улучшений исходных кодов wss в zip-архиве.
Помимо прочего, теперь вы можете проанализировать неудачное обновление (например, если требуется авторизация и возвращается код статуса, отличный от 101) и принять меры:
Также важные исправления получили StringUtils.mqh и URL.mqh.
Привет @Stanislav Korotky, я новичок в MQL5. Нашел, что вы выкладываете файл wss.zip для использования websocket. Как его использовать, есть ли демо или что-то, что я могу изучить. Искренне благодарю!