Communicating Browser Extension and external application - browser

I'm trying to connect a browser extension (Firefox, Chrome, IE...) with an external application. Using a non-polling system to notify the messages between the components.
I've already seen several approaches, but I'm not sure which ones are possible and which ones are the best.
One solution could be trying to use a IPC (Os-dependant) solution, as named pipes or sockets, but I'm not sure if I can open a named pipe in a firefox or chrome extension. Moreover, I don't know if there are any "event based" system not to need polling as a mechanism for handling the communication.
The other solution (only if I use firefox) is to use XPCOM, I think with this approach, I should instantiate a XPCOM component, implemented in the browser extension, from the External Application. I think should need the XPCOM thing as a dependency in my External Application, right?
But, using this method, is it possible to handle the communication in a asynchronous way?
Thanks in advance ;)

Related

Chrome Extension - migrating to V3 with respect to global variables and native messaging ports

I am just starting to look at the V3 manifest requirements and had the following questions.
I currently have in my background.js var settings = new usersettings(); usersettings fetches all the settings from chrome.storage.local once and then if a setting property is changed then saves it back to storage.
Do I understand it correctly that with V3 each time I need a value from settings I need to use for example chrome.storage? Further is/will the only way to retrieve storage be the following;
chrome.storage.local.get(['key'], function(result) {
console.log('Value currently is ' + result.key);
});
I am not a professional software engineer but using the above code each time I need to read a boolean setting seems very inefficient and is going to not only slow down the extension but also create a lot more code. I read that V3 will take advantage of promises is this something that can be used with chrome.storage.local.get?
I use a native messaging host. I call chrome.runtime.connectNative when the background starts up and hold the port open meaning that the Native Host which Google Chrome starts also runs. I cannot find anything on how native messaging is supposed to work with service workers. Is chrome.runtime.connectNative even useful anymore with service workers? Will the native host start and stop with the service worker? If it does how can any native code send messages to the Extension?
Is the following strategy a good idea? Is a Manifest V2 with background "persistent": false the same as a service worker? In other words instead of doing a major change to V3 could I first get my code running in V2 with a non-persistent background.js?
My native host passes some javascript to my extension which in turn adds it via the script tag. I read that in V3 that javascript cannot be retrieved by an external source. Has anyone seen anything from Google on whether the native host will be treated as an external source? On the one hand I of course can see that by definition native host code is external, however, a native host has (at least for a windows PC) much higher installation standards and user rights requirements than an extension that gets code from some external url. This is the reason for my question.
Anyone got a crystal ball on when a V2 update will be rejected?
TL;DR ManifestV3 is still a semi-broken toy that can't handle many nontrivial scenarios.
with V3 each time I need a value from settings I need to use chrome.storage
Yes.
If your data object isn't big it shouldn't be a problem.
If in doubt, use devtools profiler or performance.now() in your code to measure the impact.
native messaging host
It's broken for now.
I see a somewhat related https://crbug.com/1030305 but maybe you should open a new issue.
Is a Manifest V2 with background "persistent": false the same as a service worker?
Yes, conceptually.
However, there may be differences due to the inferior nature of service workers as this is still an immature Web technology so it doesn't support things we grew accustomed to such as dynamic script loading, ES modules, clipboard handling, DOM parsing, and a lot more.
instead of doing a major change to V3 could I first get my code running in V2 with a non-persistent background.js?
Yes, it's a good start especially since ManifestV3 is still in development.
My native host passes some javascript to my extension which in turn adds it via the script tag.
Definitely forbidden.
This code is not a part of the extension package so it can't be verified by the web store reviewers.
An alternative will be revealed when Chromium team announces their solution for Tampermonkey and similar extensions that allow installing external userscripts.
Meanwhile, try switching to a declarative approach: create rule definitions in JSON which will be processed by your extension code.
when a V2 update will be rejected?
Probably next year.
There's no official announcement yet but if Chromium developers have a bit of conscience they won't disable ManifestV2 until they fix all or most of the problems in V3, which will probably happen next year.
There's almost no active development currently for ManifestV3 problems though (other areas such as DevTools see ~100 times more meaningful activity) and seeing how Chromium team has been factually ignoring most of feedback from extension authors for the past five years, it's not exactly encouraging...
Update to the native messaging
Feb 2022
Connecting to a native messaging host using chrome.runtime.connectNative() in an extension's service worker will keep the service worker alive as long as the port is open.
https://developer.chrome.com/docs/extensions/whatsnew/

Can I start a socket.io/websocket server in browser?

There question about this before, the answer is no. But now, with browserify/webpack, can I just write code like I would on server and it will run in browser, or is there any restriction that would make this impossible?
No, you cannot. Starting a server in a browser requires access to low level functionality that simply to does not exist in a browser. Browserify cannot add fundamental low-level features to the browser that it does not have that would require additional native code support in order to make work.
Browserify can only package code that is either pure Javascript or is built on top of infrastructure that already exists in the browser or can be simulated with some pure javascript built on top of the features that do exist in the browser.
So, for example, you could take a crypto hash library from node.js that is pure javascript and does not rely on any capabilities that are not present in a browser and you could browserify it (e.g. repackage it) to use it in a browser. But, you could not take a node.js package that uses low-level UDP communication because the underlying access to UDP is not present in a browser.
In general, if the node.js code does I/O or manipulates other processes or uses any module that has native code, it will likely not work with browserify (there are a few work-arounds with some file I/O).
For additional info, see:
Does Browserify have any limitations?
Browserify Compatibility
So you don't say what your actual problem is that you're trying to solve, but usually you would start an actual server somewhere and have the browser connect to that server. If you wanted one particular browser session to appear to be the "master", you could certainly make your client/server behave that way. One client could be the master (appearing to essentially be the server itself) to other clients that connected to that same server. This would all be done by how you programmed your server and how it communicated with the various clients that connect to it. Actual servers can be made to be proxies for other clients where the client gets access to server-like functionality via the proxied connection to an actual server.

Interprocess communication between browser extension and native application

How can an interprocess communication be estabilished between a browser extension and a native application? Is there any cross-platform (Linux and Mac OS X) and cross-browser solution (Firefox, Chrome, Safari)?
The only idea that comes to my mind is using native Web technologies, i.e. embed a HTTP server in native application and use XmlHttpRequest or WebSockets. However, this sounds like clunky overkill with handful of issues (e.g. security). Is there a better alternative?
I believe the most commonly used method is websocket connections. Two examples I can think of are 1Password and LiveReload (source code available).
As far as I know, you need to open the websocket connection from within your global page to avoid cross-domain restrictions.
Also, in the past I have seen other apps watch and modify an extension's settings file. The extension just reads and writes from it's own settings store, while the other process watches the preferences file for changes. I believe this is less reliable and doesn't conform to sandboxing requirements for the Mac App Store so I would recommend the websockets method.

Utilizing Node.js Along Side Another Platform (Grails)

We have a grails application in the wild. We'd like to give users using current browsers a better experience and provide some auto-updating of pieces of the site. Looking into all the options and specifically with Grails, I'm not impressed.
I really want to use WebSockets and from the investigating I've done up to this point I believe our best option is Node.js. But obviously we can't redo our application. I like Grails.
So my idea is that we use Node.js along side Grails to basically act as a READ-ONLY proxy between the client and the data. All the Node.js application will do is pull data from the database and deliver it to the client over WebSockets.
Does that sound like a valid approach? Is this something anyone else has done?
Certainly sounds reasonable; I'd suggest using socket.io to implement your transport (it will use WebSockets if the browser supports them; otherwise it will transparently use various fallback mechanisms). You might want to use a reverse proxy like nginx to avoid any cross-origin problems, though socket.io is fairly good at avoiding them.
Node is very much about letting you use the right tool for the right part of the job, rather than being a Golden Hammer.
We aren't using websockets, but we have an Angular app that talks to the grails via REST calls, which we expose using controllers.

Easiest way to work with WebSockets in Node.js

I want to work with WebSockets in Node.js web app, and I am looking for the easiest way to do this. I've seen so many github repositories seemingly providing some ease of use.
But, I'm just looking to see if there's one that stands out as having the most support, or most widely implemented.
I was kind of leaning towards Socket.IO but I'm not entirely sure.
Any advice?
Thanks!
use now now or socket.io.
now is an abstraction build on socket.io which allows you to define methods on a shared object across client and server. This means you dont have to interact with the stream manually and can just seemingly call methods. Do read their best practices before use though.
now also has a grouping system in build which means you can talk to clients in groups rather then one or all.
socket.io itself is recommended because of it's excellent browser support with its range of fallbacks. It's also owned/maintained by a node.js startup so it's more likely to be maintained in the future. And it also has a range of server-side socket.io implementations for platforms other then node.js so you can use the same API on multiple platforms.
If you find socket.IO too large or bloated you can go for the lightweight websocket-server. This is just a simple websocket implementation and is reasonably stable. I have personally used this if I want something which is a very minimal abstraction and if I want more low level access to the websocket server itself.
Take a look at this blog post, it's very informative...

Resources