Java和chrome扩展,本机消息

时间:2016-06-29 10:04:53

标签: javascript java google-chrome google-chrome-extension chrome-native-messaging

我尝试在我的电脑上进行调用java代码的chrome扩展。调用工作正常,代码执行,但我尝试将变量返回到chrome扩展但不起作用。我在控制台中看到监听器onDisconect写了一个控制台消息,但监听器onMessage没有。我不知道这个问题。

以下是Chrome扩展程序中的代码:

Manifest JSON

{
    "name": "Prueba native message",
    "version": "1.0",
    "manifest_version": 2,
    "description": "Chrome extension interacting with Native Messaging and     localhost.",
    "app": {
    "background": {
        "scripts": ["background.js"]
    }
},
    "icons": {
    },
    "permissions": [
        "nativeMessaging"
    ]
}

background.js

var port = chrome.runtime.connectNative('com.app.native');

function message(msg) {
    console.warn("Received" + msg);
}

function disconect() {
    console.warn("Disconnected");
}

console.warn("se ha conectado");

port.onMessage.addListener(message);
port.onDisconnect.addListener(disconect);
port.postMessage({text: "Hello, my_application"});

console.warn("message send");

这是我的本地文件。

.bat

cd C:\Users\pc\IdeaProjects\eDNI\out\production\code && java Main

Main.java

public class Main {
    public static void main(String argv[]) throws IOException {
        System.out.println("{\"m\":\"hi\"");
    }
}

在此代码中,我只尝试将一条简单的消息返回到扩展名。

2 个答案:

答案 0 :(得分:1)

  

原生邮件协议

     

Chrome启动每个本机消息传递主机   一个单独的过程,并使用标准输入与它通信   (stdin)和标准输出(stdout)。使用相同的格式发送   两个方向的消息:使用JSON序列化每条消息,   UTF-8编码,并且在本机中以32位消息长度开头   字节顺序。来自本机的单个消息的最大大小   消息传递主机为1 MB,主要是为了保护Chrome免受行为不端的影响   原生应用。发送给的消息的最大大小   本机消息传递主机为4 GB。

来源: Native Messaging Protocol

前四个字节需要是消息的长度。您需要将消息长度(整数)转换为字节数组:

选项1:使用java.nio.ByteBuffer

'Yes, I have...'

选项2:手动:

public byte[] getBytes(int length) {
    ByteBuffer b = ByteBuffer.allocate(4);
    b.putInt(length);
    return b.array();
}

写出消息长度,然后写出消息内容,以字节为单位。

public byte[] getBytes(int length) {
    byte[] bytes = new byte[4];
    bytes[0] = (byte) (length & 0xFF);
    bytes[1] = (byte) ((length >> 8) & 0xFF);
    bytes[2] = (byte) ((length >> 16) & 0xFF);
    bytes[3] = (byte) ((length >> 24) & 0xFF);
    return bytes;
}

<强>更新

看起来您还缺少需要在清单文件中指定的接口类型。

添加:String message = "{\"m\":\"hi\"}"; System.out.write(getBytes(message.length())); System.out.write(message.getBytes("UTF-8")); System.out.flush();

答案 1 :(得分:0)

我在chrome上使用本机主机已有一段时间了。这是如何开发的,请注意前面有关以字节数组形式发送数据的注释。这部分至关重要。该项目的本机主机和扩展部分以及文档也可以在此github

上找到。

扩展名和文档:https://github.com/esabilbulbul/ss-ext-barcode-web 本机主机(java):https://github.com/esabilbulbul/ss-app-barcode-nativehost-java 本机主机(cpp):https://github.com/esabilbulbul/ss-app-barcode-nativehost-cpp

清单jSON

{
"manifest_version": 2, "version": "1.0", "name": "Hello World 3", "icons":
{
"128":"icons/icon128.png", "48":"icons/icon48.png", "16":"icons/icon16.png"
}, "page_action": {
"default_icon":"/icons/icon16.png",
"default_popup":"popup.html" },
"content_scripts": [
    {
        "matches":[
"http://localhost:8080/*/*",
"http://localhost:8080/ss-web- client/SHIPSHUK/WEBSITE/pages/merchant/reports/posdekont/mybizstats.html"
], "js":["content.js"]
} ],
"background": {
"scripts":["background.js"],
"persistent": false },
"permissions": [
"nativeMessaging", "activeTab",
"tabs", "http://localhost:8080/*/*"
] }
"externally_connectable": {
"matches": [ ],
"http://localhost:8080/*/*"
"ids":[ "fhbnbigbjcmhllmfccoomobllianhofe", "*"
] },

我使用此代码从页面向扩展发送消息

var editorExtensionId = 'fhbnbigbjcmhllmfccoomobllianhofe';
//chrome.runtime.sendMessage({todo: "showPageAction", value: 'test'}); //window.postMessage({ type: "showPageAction", todo: "showPageAction", text: "Hello from the webpage!" }, "*");
// Make a simple request:
chrome.runtime.sendMessage(editorExtensionId, {todo: "showPageAction", value: 'test2'});

本地主机在铬上的注册:您还需要注册Chrome的本地主机。如果您使用的是Windows,请使用regadd进行操作;如果您使用的是Linux或Mac,请使用regadd进行操作;在chrome下的nativemessaginghosts文件夹下创建一个json文件。在我的情况下,该文件夹是 / Users / esabil / Library / Application Support / Google / Chrome / NativeMessagingHosts

最后一部分是NATIVE HOST APP。您可以使用任何语言来执行此操作,只要您使用stdio。我用java和cpp做到了。这是我的Java部分

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package nativehost;

import java.io.IOException;

/**
 *
 * @author esabil
 */
public class main {

    /**
     * @param args the command line arguments
     * 
     * 
     * This is NATIVE MESSAGING HOST of Chrome Extension for Barcode Printing (SHIPSHUK)
     * 
     */
    public static void main(String[] args)
    {
        // TODO code application logic here
        //System.out.println("NativeHost app is starting");
        
        String sIncomingMsg = receiveMessage();
        
        String sOutgoingMsg = "{\"text\":\"java host\"}";
        
        sendMessage(sOutgoingMsg);
        
    }

    //Convert length from Bytes to int
    public static int getInt(byte[] bytes) 
    {
        return  (bytes[3] << 24) & 0xff000000|
                (bytes[2] << 16)& 0x00ff0000|
                (bytes[1] << 8) & 0x0000ff00|
                (bytes[0] << 0) & 0x000000ff;
    }

    // Read an input from Chrome Extension
    static public String receiveMessage()
    {

        byte[] b = new byte[4];

        try
        {
            System.in.read(b);
            int size = getInt(b);

            byte[] msg = new byte[size];
            System.in.read(msg);

            // make sure to get message as UTF-8 format
            String msgStr = new String(msg, "UTF-8");

            return msgStr;

        }
        catch (IOException e)
        {
            e.printStackTrace();
            return null;
        }

    }
    
    public static byte[] getBytes(int length) 
    {
        byte[] bytes = new byte[4];
        bytes[0] = (byte) ( length      & 0xFF);
        bytes[1] = (byte) ((length>>8)  & 0xFF);
        bytes[2] = (byte) ((length>>16) & 0xFF);
        bytes[3] = (byte) ((length>>24) & 0xFF);
        return bytes;
    }

    static public void sendMessage(String pMsg)
    {
        try 
        {
            System.out.write(getBytes(pMsg.length()));
            
            byte[] bytes = pMsg.getBytes();
            
            System.out.write(bytes);
        } 
        catch (IOException ex) 
        {
            ex.printStackTrace();
        }
    }


}