c# json google-chrome-extension chrome-native-messaging

Muy lento para pasar una cantidad de datos "grande" de Chrome Extension a Host(escrito en C#)



json google-chrome-extension (1)

Estoy usando la API Native Messaging API de Chrome para pasar el DOM de una página a mi host. Cuando trato de pasar una pequeña cadena de mi extensión a mi host, todo funciona, pero cuando intento pasar todo el DOM (que no es tan grande ... solo alrededor de 260 KB), todo va mucho más lento y finalmente obtengo un Native host has exited error impide que el host responda.

Mi pregunta principal: ¿Por qué tarda tanto pasar un mensaje de 250 KB a 350 KB de la extensión al host?

De acuerdo con el sitio del desarrollador :

Chrome inicia cada host de mensajería nativo en un proceso separado y se comunica con él usando la entrada estándar (stdin) y la salida estándar (stdout). El mismo formato se utiliza para enviar mensajes en ambas direcciones: cada mensaje se serializa usando JSON, UTF-8 codificado y va precedido con una longitud de mensaje de 32 bits en orden de bytes nativo. El tamaño máximo de un solo mensaje del host de mensajería nativo es de 1 MB, principalmente para proteger a Chrome de las aplicaciones nativas que no funcionan correctamente. El tamaño máximo del mensaje enviado al host de mensajería nativo es de 4 GB.

La página cuyos DOMs estoy interesado en enviar a mi host no son más de 260 KB (y en ocasiones 300 KB), muy por debajo del máximo impuesto de 4 GB.

popup.js

document.addEventListener(''DOMContentLoaded'', function() { var downloadButton = document.getElementById(''download_button''); downloadButton.addEventListener(''click'', function() { chrome.tabs.query({currentWindow: true, active: true}, function (tabs) { chrome.tabs.executeScript(tabs[0].id, {file: "getDOM.js"}, function (data) { chrome.runtime.sendNativeMessage(''com.google.example'', {"text":data[0]}, function (response) { if (chrome.runtime.lastError) { console.log("Error: " + chrome.runtime.lastError.message); } else { console.log("Response: " + response); } }); }); }); }); });

host.exe

private static string StandardOutputStreamIn() { Stream stdin = new Console.OpenStandardInput(); int length = 0; byte[] bytes = new byte[4]; stdin.Read(bytes, 0, 4); length = System.BitConverter.ToInt32(bytes, 0); string = ""; for (int i=0; i < length; i++) string += (char)stdin.ReadByte(); return string; }

Tenga en cuenta que encontré el método anterior de esta pregunta.

Por el momento, solo intento escribir la cadena en un archivo .txt:

public void Main(String[] args) { string msg = OpenStandardStreamIn(); System.IO.File.WriteAllText(@"path_to_file.txt", msg); }

  1. Escribir la cadena en el archivo lleva mucho tiempo (~ 4 segundos, y a veces hasta 10 segundos).
  2. La cantidad de texto que se escribe realmente varía, pero nunca es más que la declaración del documento superior y algunas etiquetas de comentarios de IE. Todo el texto ahora aparece.
  3. Este archivo con apenas texto es de 649 KB, pero el documento real solo debería tener 205 KB (cuando lo descargue). El archivo aún es un poco más grande de lo que debería ser (216 KB cuando debería ser de 205 KB).

getDOM.js mi función getDOM.js simplemente descargando el archivo, y todo el proceso es casi instantáneo.

No estoy seguro de por qué este proceso lleva tanto tiempo, por qué el archivo es tan grande o por qué apenas se está enviando realmente el mensaje.

No estoy seguro si esto tiene algo que ver con deserializar el mensaje de una manera específica, si debo crear un puerto en lugar de usar chrome.runtime.sendNativeMessage(...); método, o si hay algo completamente diferente que me falta.

¡Toda ayuda es muy apreciada! ¡Gracias!

EDITAR

Aunque mi mensaje está enviando correctamente DESDE la extensión AL host, ahora estoy recibiendo un Native host has exited error antes de que la extensión reciba el mensaje del host.


Esta pregunta básicamente es: "¿Cómo puedo leer de manera eficiente y rápida la información de la entrada estándar?"

En el código anterior, el problema no es entre la extensión de Chrome y el host, sino entre la entrada estándar y el método que lee de la corriente de entrada estándar, a saber, StandardOutputStreamIn() .

La forma en que funciona el método en el código del OP es que un bucle se ejecuta a través de la secuencia de entrada estándar y continuamente concatena la cadena de input con una nueva cadena (es decir, el carácter que lee de la secuencia de bytes). Esta es una operación costosa , y podemos evitar esto al crear un objeto StreamReader para captar toda la secuencia de una vez (especialmente dado que conocemos la información de longitud contenida en los primeros 4 bytes). Por lo tanto, solucionamos el problema de la velocidad con:

public static string OpenStandardStreamIn() { //Read 4 bytes of length information System.IO.Stream stdin = Console.OpenStandardInput(); int length = 0; byte[] bytes = new byte[4]; stdin.Read(bytes, 0, 4); length = System.BitConverter.ToInt32(bytes, 0); char[] buffer = new char[length]; using (System.IO.StreamReader sr = new System.IO.StreamReader(stdin)) { while (sr.Peek() >= 0) { sr.Read(buffer, 0, buffer.Length); } } string input = new string(buffer); return input; }

Si bien esto soluciona el problema de velocidad, no estoy seguro de por qué la extensión arroja un Native host has exited error .