Java和chrome扩展,本机消息

Java and chrome extension, natives messages

本文关键字:本机 消息 扩展 chrome Java      更新时间:2023-09-26

我尝试做一个chrome扩展调用java代码在我的PC。调用工作正常,代码执行,但我试图返回变量到chrome扩展,但不工作。我在控制台中看到侦听器onDisconect写入了一条控制台消息,但侦听器onMessage没有。我不知道是什么问题。

这是我的代码在chrome扩展:

清单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'"");
    }
}

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

本地消息传递协议

Chrome启动每个本地消息主机一个独立的进程,并使用标准输入与之通信(stdin)和标准输出(stdout)。使用相同的格式发送双向消息:每个消息都使用JSON序列化,UTF-8编码的,前面是本机的32位消息长度字节顺序。来自本机的单个消息的最大大小消息主机是1mb,主要是为了保护Chrome免受不当行为本机应用程序。发送到的最大消息大小本机消息主机为4gb。

来源:本地消息传递协议

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

选项1:使用java.nio.ByteBuffer类

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

选项2:手册:

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();

更新:

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

添加:"type": "stdio"

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

上获得。

扩展名+ Doc: 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'});

NATIVE HOST REGISTRY ON CHROME:您还需要为CHROME注册本机主机。如果你是在Windows上,用regadd做,如果你是在linux或mac上,在chrome下的nativemessaginghosts文件夹下创建一个json文件。在我的情况下,文件夹是/用户/esabil/图书馆/应用支持/谷歌/铬/NativeMessagingHosts

最后一部分是NATIVE HOST应用程序。你可以用任何语言做这个,只要你使用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();
        }
    }

}