最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Chrome Native messaging with PHP - Stack Overflow

programmeradmin1浏览0评论

I am trying to build a PHP class that can municate with a Chrome Extention through Native Messaging.

I can connect to my code, but at initiation Chrome sends

chrome-extension://lkjcciocnocjjgpacggbaikjehbfedbl/ --parent-window=1837060

To my PHP console app (The Host). What do I reply to make the connection working? Below my PHP code. Yes its dirty because its a POC project and I am very new to Chrome Extensions especially with the current updates.

function out($data = ""){
    $fp = fopen("php://stdout", "w");
    if($fp){
        $response = array("text" => "Ok");
        $message = json_encode($response);
        fwrite($fp, $message);
        fflush($fp);
        slog("[OUTPUT] " . json_encode($response));
        fclose($fp);
        exit(0);
    }else{
        slog("Can't open output stream.");
        exit(1);
    }
}

function err($data){
    $fp = fopen("php://stderr", "w");
    if($fp){
        fwrite($fp, $data);
        fflush($fp);
        fclose($fp);
    }
    return;
}

function in(){
    $data = "";
    $fp = fopen("php://stdin", "r");
    if($fp){
        $data = fgets($fp);
        fclose($fp);       
    }else{
        slog("Can't open input stream.");
        exit(1);
    }
    slog("[INPUT]" . $data);
    return $data;
}

function slog($data){
    if($data != ""){
        file_put_contents("./log.txt", date("r").": {$data}\r\n", FILE_APPEND);
    }
}

slog("Entering");
while(true){
    if(($l = in()) !== ""){
        out($l);
    }else{
        exit(0);
    }
}
exit(0);

My background.js code. (the extention)

var port = null;
var hostName = ".google.chrome.poc-extension";

function appendMessage(text) {
  document.getElementById('response').innerHTML += "<p>" + text + "</p>";
}

function updateUiState() {
  if (port) {
      document.getElementById('connect-button').style.display = 'none';
  }else{
      document.getElementById('connect-button').style.display = 'block';
  }
}

function sendNativeMessage() {
  port = chrome.runtime.connectNative(hostName);
  port.onMessage.addListener(onNativeMessage);

  message = {"text": document.getElementById('input-text').value};
  port.postMessage(message);
  appendMessage("Sent message: <b>" + JSON.stringify(message) + "</b>");
}
function onNativeMessage(message) {
  alert(message);
  appendMessage("Received message: <b>" + JSON.stringify(message) + "</b>");
}
function onDisconnected() {
  appendMessage("Failed to connect: " + chrome.runtime.lastError.message);
  console.log(chrome.runtime.lastError);
  port = null;
  updateUiState();
}
function connect() {  
  appendMessage("Connecting to native messaging host <b>" + hostName + "</b>")
  port = chrome.runtime.connectNative(hostName);
  port.onMessage.addListener(onNativeMessage);
  port.onDisconnect.addListener(onDisconnected);
  updateUiState();
}
document.addEventListener('DOMContentLoaded', function (){    
    document.getElementById('connect-button').addEventListener('click', connect);
    document.getElementById('send-message-button').addEventListener('click', sendNativeMessage);
    updateUiState();
});

There is this Python example app but I don't really get what it does exactly. Besides that it also uses the Tkinter plugin which I don't want. I want a clean, plain and simpel extension.

I am trying to build a PHP class that can municate with a Chrome Extention through Native Messaging.

I can connect to my code, but at initiation Chrome sends

chrome-extension://lkjcciocnocjjgpacggbaikjehbfedbl/ --parent-window=1837060

To my PHP console app (The Host). What do I reply to make the connection working? Below my PHP code. Yes its dirty because its a POC project and I am very new to Chrome Extensions especially with the current updates.

function out($data = ""){
    $fp = fopen("php://stdout", "w");
    if($fp){
        $response = array("text" => "Ok");
        $message = json_encode($response);
        fwrite($fp, $message);
        fflush($fp);
        slog("[OUTPUT] " . json_encode($response));
        fclose($fp);
        exit(0);
    }else{
        slog("Can't open output stream.");
        exit(1);
    }
}

function err($data){
    $fp = fopen("php://stderr", "w");
    if($fp){
        fwrite($fp, $data);
        fflush($fp);
        fclose($fp);
    }
    return;
}

function in(){
    $data = "";
    $fp = fopen("php://stdin", "r");
    if($fp){
        $data = fgets($fp);
        fclose($fp);       
    }else{
        slog("Can't open input stream.");
        exit(1);
    }
    slog("[INPUT]" . $data);
    return $data;
}

function slog($data){
    if($data != ""){
        file_put_contents("./log.txt", date("r").": {$data}\r\n", FILE_APPEND);
    }
}

slog("Entering");
while(true){
    if(($l = in()) !== ""){
        out($l);
    }else{
        exit(0);
    }
}
exit(0);

My background.js code. (the extention)

var port = null;
var hostName = ".google.chrome.poc-extension";

function appendMessage(text) {
  document.getElementById('response').innerHTML += "<p>" + text + "</p>";
}

function updateUiState() {
  if (port) {
      document.getElementById('connect-button').style.display = 'none';
  }else{
      document.getElementById('connect-button').style.display = 'block';
  }
}

function sendNativeMessage() {
  port = chrome.runtime.connectNative(hostName);
  port.onMessage.addListener(onNativeMessage);

  message = {"text": document.getElementById('input-text').value};
  port.postMessage(message);
  appendMessage("Sent message: <b>" + JSON.stringify(message) + "</b>");
}
function onNativeMessage(message) {
  alert(message);
  appendMessage("Received message: <b>" + JSON.stringify(message) + "</b>");
}
function onDisconnected() {
  appendMessage("Failed to connect: " + chrome.runtime.lastError.message);
  console.log(chrome.runtime.lastError);
  port = null;
  updateUiState();
}
function connect() {  
  appendMessage("Connecting to native messaging host <b>" + hostName + "</b>")
  port = chrome.runtime.connectNative(hostName);
  port.onMessage.addListener(onNativeMessage);
  port.onDisconnect.addListener(onDisconnected);
  updateUiState();
}
document.addEventListener('DOMContentLoaded', function (){    
    document.getElementById('connect-button').addEventListener('click', connect);
    document.getElementById('send-message-button').addEventListener('click', sendNativeMessage);
    updateUiState();
});

There is this Python example app but I don't really get what it does exactly. Besides that it also uses the Tkinter plugin which I don't want. I want a clean, plain and simpel extension.

Share Improve this question edited Nov 13, 2017 at 16:59 Digital Human asked Nov 13, 2017 at 16:50 Digital HumanDigital Human 1,6471 gold badge19 silver badges27 bronze badges 8
  • The first quote isn't sent to stdin, those are mand line parameters. If you see it in your php code then something is wrong. As for the python example, the meaningful part is send_message and read_thread_func. The protocol is simple and described in the documentation: 4 bytes length, JSON-ified message. – woxxom Commented Nov 13, 2017 at 17:50
  • Sounds plausible indeed. Gonna check and reply soon. – Digital Human Commented Nov 14, 2017 at 7:07
  • @wOxxOm chrome doesn't seem to pipe stdin correctly. I use a windows .bat file, like the example Python app. echo %* | php -f "%~dp0/native_host.php" – Digital Human Commented Nov 14, 2017 at 8:22
  • echo %* prints your mand line into stdin, which is hardly what you want. The documentation's bat file doesn't do that. – woxxom Commented Nov 14, 2017 at 9:16
  • I tried only with php -f "%~dp0/native_host.php" but that doesn't work either.......kind stuck here – Digital Human Commented Nov 14, 2017 at 13:15
 |  Show 3 more ments

1 Answer 1

Reset to default 11 +25

Native Messaging use structured data (length-formatted) to read and write. in browser (JavaScript), that structure has been handled by browser. If you want to municate with Native Messaging, so you need to follow that structure. Read refference here

Each message is serialized using JSON, UTF-8 encoded and is preceded with 32-bit message length in native byte order.

So you need to send your message as: len(message) + [your message]

len(message) must be packed following the protocol.

Example function to send output:

function out($data = ""){
    $fp = fopen("php://stdout", "w");
    if($fp){
        $response = array("text" => "Ok");
        $message = json_encode($response);
        //Send the length of data
        fwrite($fp, pack('L', strlen($message)));
        fwrite($fp, $message);
        fflush($fp);
        slog("[OUTPUT] " . json_encode($response));
        fclose($fp);
        exit(0);
    }else{
        slog("Can't open output stream.");
        exit(1);
    }
}

Read Input:

function in(){
    $data = "";
    $fp = fopen("php://stdin", "r");
    if($fp){
        //Read first 4 bytes as unsigned integer
        $len    = current( unpack('L', fread($fp, 4) ) );
        $data   = fread($fp, $len);
        fclose($fp);
    }else{
        slog("Can't open input stream.");
        exit(1);
    }
    slog("[INPUT]" . $data);
    return $data;
}
发布评论

评论列表(0)

  1. 暂无评论