JavaScript is required to use Bungie.net

Group Avatar

BungieNetPlatform

"Updates, discussions, and documentation of the BungieNetPlatform API."

Request Join
originally posted in:BungieNetPlatform
8/29/2014 11:13:11 AM
0

Communication between browser and external program

One of the problems some people will undoubtedly come across is needing to access information held by a browser in their own applications. For bungie.net you may want to access cookie information, histories, and so on and modify the page based on some external event or vice-versa; do something external to the browser when something occurs within it. What I've been experimenting with for a while now is Chrome's [url=https://developer.chrome.com/extensions/messaging#native-messaging]message passing API[/url] to a non-Chrome process, so I wanted to give a little tutorial on how you might go about this as well. [b]1. Create the [i]native host[/i] application[/b] This is the application you'll create which will be started when a [url=https://developer.chrome.com/extensions/runtime#method-connectNative]Chrome port is instantiated[/url]. It only requires you to manage both the standard input and output streams, so you can use anything which gives you that ability. For this example I'll assume you're using C#, though. First thing you'll need to do as I mentioned is manage the streams which are connected to the other end of the Chrome extension you'll also make.[quote]Stream stdin = Console.OpenStandardInput(); Stream stdout = Console.OpenStandardOutput();[/quote]Simple enough. Messages passed between the extension and application are formatted as follows: | [i]length[/i]: 4 bytes | data: [i]length[/i] bytes | So it's just a matter of reading what the length is, allocating a buffer of that length, then reading the rest.[quote]int len; byte[] buff = new byte[4]; string str; stdin.Read(buff, 0, 4); len = BitConverter.ToInt32(buff, 0); buff = new byte[len]; stdin.Read(buff, 0, len); str = Encoding.UTF8.GetString(buff);[/quote]Done. str holds the message from the extension. Sending a message back is really just the reverse.[quote] string str = "{\"msg\": \"hello, world\"}"; byte[] buff = Encoding.UTF8.GetBytes(str); stdout.Write(BitConverter.GetBytes(buff.Length), 0, 4); //Write the length stdout.Write(buff, 0, buff.Length); //Write the message[/quote]Don't forget to encode and decode using UTF8. 2. [b]Create the [i]native client[/i] extension[/b] First thing you'll need to do is set up a manifest for locating your application. So, in an appropriate place, create a manifest.json file in the following format and save it.[quote]{ "name": "com.example.helloworld", "description": "Hello World App", "path": "[i]Absolute path to the executable you created[/i]", "type": "stdio", "allowed_origins": [ "chrome-extension://[i]extension id of the extension making use of the native host[/i]/" ] }[/quote]The next step depends on your platform, but I'll assume you're using Windows. For others, see [url=https://developer.chrome.com/extensions/messaging#native-messaging-host]here[/url]. Open up the registry editor (regedit), filter down to Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts, and right click the NativeMessagingHosts directory and choose "New Key". Rename it with the name you put in your manifest.json file (eg. "com.example.helloworld"), and then modify the (Default) key you see in the right panel and in the value input paste in the absolute path to the manifest.json file you created. Now create a new Chrome extension (or look for an existing one you're developing) and find the extension ID from the chrome://extensions page and paste it into the manifest.json file in the allowed_origins array where the italic placeholder text is (above). In the permissions for your extension, make sure you include "nativeMessaging". Now you've finished part one. Part two. In an appropriate place in your extension's scripts (eg. a background.js script), do the following:[quote] var port = chrome.runtime.connectNative("com.example.helloworld");[/quote]At this point your program you created previously should have started running (you can check with Task Manager) and the extension should be connected to it. To send a message to the program you just pass an object to the postMessage function:[quote]port.postMessage( {msg: "Hello world!"} );[/quote]To receive replies, just add an event handler:[quote]port.onMessage.addListener(function(r){ alert(r.msg); });[/quote]Simple. [b]3. Misc[/b] - Even if you disconnect the port from within the Chrome extension, the program will continue to run. It may be wise to use heartbeat system for checking if the other end of the stream is still there and exit if it's not. - For .NET users, be careful when using reading from the stream within a loop and ignoring the exceptions. If you do, you'll end up infinite-looping and you'll need to terminate from the task manager. - Use console.log in your extension and check the console output in the background page! - Once you disconnect a Port (deliberately or not), you can't reuse it. - If you're using Visual Studio and get somewhat further than this basic tutorial, start routing incoming messages to another process which is being debugged by Visual Studio so you can better see what's happening. - Do use a JSON library such as JSON.NET for serialisation/deserialisation of objects between the program and extension. - There is apparently a limit on the maximum length of a message (which isn't 2^31-1). It is apparently much lower, although I haven't hit it yet. If you do, you probably need to devise a way of fragmenting your messages.

Posting in language:

 

Play nice. Take a minute to review our Code of Conduct before submitting your post. Cancel Edit Create Fireteam Post

You are not allowed to view this content.
;
preload icon
preload icon
preload icon