Я разрабатываю расширение для Chrome, работающее с собственным хостом обмена сообщениями.
В большинстве случаев это работает, но я обнаружил странное поведение при отправке сообщений определенных размеров.
Кажется, что сообщение сбрасывается, когда размер составляет от 2560 до 2815 байт (A00 и AFF в шестнадцатеричном формате). Все последующие сообщения также не приходят, что говорит о том, что поток по какой-то причине поврежден.
Вот урезанное собственное приложение обмена сообщениями Python, которое можно использовать для его проверки:
import sys
import struct
def output(message):
encoded_message = message.encode('utf-8')
# Write message size.
sys.stdout.write(struct.pack('I', len(encoded_message)))
# Write the message itself.
sys.stdout.write(encoded_message)
sys.stdout.flush()
if __name__ == "__main__":
output('{"type": "%s"}' % ('x'*2820))
output('{"type": "%s"}' % ('x'*2560))
Я получаю первое сообщение, а не второе.
Я взглянул на код в Хром репозиторий. Функция, которая, кажется, отвечает за эту функциональность, не имеет ничего особенного:
void NativeMessageProcessHost::ProcessIncomingData(
const char* data, int data_size) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
incoming_data_.append(data, data_size);
while (true) {
if (incoming_data_.size() < kMessageHeaderSize)
return;
size_t message_size =
*reinterpret_cast<const uint32*>(incoming_data_.data());
if (message_size > kMaximumMessageSize) {
LOG(ERROR) << "Native Messaging host tried sending a message that is "<< message_size << " bytes long.";
Close(kHostInputOuputError);
return;
}
if (incoming_data_.size() < message_size + kMessageHeaderSize)
return;
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(&Client::PostMessageFromNativeProcess, weak_client_ui_,
destination_port_,
incoming_data_.substr(kMessageHeaderSize, message_size)));
incoming_data_.erase(0, kMessageHeaderSize + message_size);
}
}
Кто-нибудь знает, что здесь происходит?
Обновить
Я столкнулся с этой проблемой в 64-разрядных версиях Windows 7 и Windows 8.1.
Я попробовал Chrome 64-bit на каналах Stable, Beta и Dev — версии 37, 38 и 39.
Я также попробовал стабильный 32-битный Chrome
Я использую 32-битную версию Python 2.7.7 и PyInstaller 2.1 для создания исполняемого файла для собственного узла обмена сообщениями.
Поскольку вы используете Windows, я подозреваю, что Windows добавляет возврат каретки (\x0D
) переводить символы (\x0A
).
В соответствии с Python 2.x — записать двоичный вывод в стандартный вывод?, Чтобы предотвратить изменение выходного потока в Windows, используйте следующий фрагмент перед записью чего-либо в стандартный вывод.
if sys.platform == "win32":
import os, msvcrt
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)