-->

How to implement chrome native messaging message h

2019-05-23 00:55发布

问题:

I tried to implement native messaging protocol in java but it didn't work.
I tried it following way.

private String readMessage() {

        int length = getInt(getLength());

        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        byte[] b = new byte[4];

        try {
            int total;
            for(int totalRead = 0 ; totalRead < length ; totalRead = totalRead + 4){
            System.in.read(b); // make sure
                bOut.write(b);
            }

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

        String bRes = null;
        try {
            bRes = new String(bOut.toByteArray(), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return bRes;

    }

To read size i have used following methods:

This construct the int from first four bytes

    private int getInt(byte[] bytes)
    {
        return (bytes[3] << 24) & 0xff000000 |
                (bytes[2] << 16) & 0x00ff0000 |
                (bytes[1] << 8) & 0x0000ff00 |
                (bytes[0] << 0) & 0x000000ff;
    }

This reads first four bytes and returns byte array

private byte[] getLength()
        {
            int length = 0 ;
            byte[] bytes = new byte[4];
            try
            {
                 System.in.read(bytes);

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


            return bytes;

    }

This gives "Error when communicating with the native messaging host" error. How can i implement this protocol correctly in java.
Can someone provide simple working example for java

回答1:

My approach below gives a Java implementation that receives a message from a Chrome App and sends a message back. On my little-endian machine it works.

I haven't properly studied your effort but hopefully this will help with your 'simple working example' request.

The main points: Communication is with the standard stream. As you know, read in the first 4 bytes separately to learn the length (here, in to lengthByte):

byte[] lengthByte = new byte[4];
int bytesRead = System.in.read(lengthByte,0,4);

//Read the message into byte[] c:
byte[] c = new byte[text_length];
int lengthAppMessage = System.in.read(c,0,text_length);

When writing back to the app, we write the message length in the 1st 4 bytes. For the message {"m":"hi"}, which is the message I send below, the message length is 10. (For {"m":"hello"} it's 13, etc.)

int returnedMessageLength = 10;

System.out.write((byte) (returnedMessageLength));
System.out.write((byte)0);
System.out.write((byte)0);
System.out.write((byte)0);

Where the last three lines are padding to sum to 4 bytes. You may need to put these three lines in to the stream before the message length.

When appending the message, the {"...":"..."} format is needed. We can send the message through in sections e.g.

System.out.append('{');
System.out.append('"');
System.out.append('m');
System.out.append('"');
System.out.append(':');
System.out.append('"');
System.out.append('h');
System.out.append('i');
System.out.append('"');
System.out.append('}');  

The point is that breaking the message in to sections and sending each section separately circumnavigates the Java formatting problem (caused by the single outer quotes.)

Put all of the above code inside a never-ending 'while' loop to avoid exiting too soon. (To see this code running, I integrated it with the example from Google's native messaging page.)

This is not good code that I've used, but either by accident or design, it worked this way for me.



回答2:

The below codes works well on my side.

//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;
    }

}