2015-06-17 10 views
19

Ho trascorso alcune ore alla ricerca di come ottenere la messaggistica nativa di Chrome che funziona con un host nativo C#. Concettualmente è stato abbastanza semplice, ma c'erano un paio di strappi che ho risolto con l'aiuto (in parte) da queste altre domande:Host nativo C# con Chrome Native Messaging

Native Messaging Chrome
Native messaging from chrome extension to native host written in C#
Very Slow to pass "large" amount of data from Chrome Extension to Host (written in C#)

La mia soluzione è pubblicato qui di seguito.

risposta

24

Assumendo il manifesto è impostato correttamente, ecco un esempio completo per parlare con un C# host utilizzando il metodo "porta":

using System; 
using System.IO; 
using Newtonsoft.Json; 
using Newtonsoft.Json.Linq; 

namespace NativeMessagingHost 
{ 
    class Program 
    { 
     public static void Main(string[] args) 
     { 
     JObject data; 
     while ((data = Read()) != null) 
     { 
      var processed = ProcessMessage(data); 
      Write(processed); 
      if (processed == "exit") 
      { 
       return; 
      } 
     } 
     } 

     public static string ProcessMessage(JObject data) 
     { 
     var message = data["text"].Value<string>(); 
     switch (message) 
     { 
      case "test": 
       return "testing!"; 
      case "exit": 
       return "exit"; 
      default: 
       return "echo: " + message; 
     } 
     } 

     public static JObject Read() 
     { 
     var stdin = Console.OpenStandardInput(); 
     var length = 0; 

     var lengthBytes = new byte[4]; 
     stdin.Read(lengthBytes, 0, 4); 
     length = BitConverter.ToInt32(lengthBytes, 0); 

     var buffer = new char[length]; 
     using (var reader = new StreamReader(stdin)) 
     { 
      while (reader.Peek() >= 0) 
      { 
       reader.Read(buffer, 0, buffer.Length); 
      } 
     } 

     return (JObject)JsonConvert.DeserializeObject<JObject>(new string(buffer)); 
     } 

     public static void Write(JToken data) 
     { 
     var json = new JObject(); 
     json["data"] = data; 

     var bytes = System.Text.Encoding.UTF8.GetBytes(json.ToString(Formatting.None)); 

     var stdout = Console.OpenStandardOutput(); 
     stdout.WriteByte((byte)((bytes.Length >> 0) & 0xFF)); 
     stdout.WriteByte((byte)((bytes.Length >> 8) & 0xFF)); 
     stdout.WriteByte((byte)((bytes.Length >> 16) & 0xFF)); 
     stdout.WriteByte((byte)((bytes.Length >> 24) & 0xFF)); 
     stdout.Write(bytes, 0, bytes.Length); 
     stdout.Flush(); 
     } 
    } 
} 

Se non c'è bisogno di comunicare attivamente con l'host, usando runtime.sendNativeMessage funzionerà bene. Per evitare che l'host si blocchi, basta rimuovere il ciclo while e leggere/scrivere una volta.

Per verificare ciò, ho usato il progetto di esempio fornito da Google qui: https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/docs/examples/api/nativeMessaging

Nota: sto usando Json.NET per semplificare il processo di serializzazione JSON/de-serializzazione.

Spero che questo sia utile a qualcuno!

+0

Sto cercando questo per Java ma non riesco a trovarlo da nessuna parte:/ – farukdgn

+0

@farukdgn In particolare, cosa si sta dimostrando difficile da trovare? Un'implementazione Java dovrebbe essere abbastanza simile. – itslittlejohn

+0

Sì, grazie, è un inizio perfetto! – shaune