2

I will try to make this as short as possible. I have been struggling for the past 6 hours trying to find a way to make a Chrome Extension communicate with a Node.js script on my machine. I first attempted to use socket.io, but after a few hours of experimenting and trying it out, I found it that you cannot use require on a Chrome Extension. My second attempt was to use chrome.sockets, and after some research, I found out that you cannot use chrome.sockets either. I am currently lost and have no idea what to do in order to achieve a communication between the two.

What I want is for the script on my machine to be the server, and the Chrome Extension to be the client. The client will not be receiving any requests, just sending, and the server of course will only be receiving requests.

This is what I have so far:

Server:

var app = require('http').createServer(handler).listen(3690);
var io = sockets(app)

function handler(req,res){
    console.log(req.url);
    res.writeHead(200, {'Content-Type':'text/plain'});
    res.end('Hello Node\n You are really really awesome!');
}

io.sockets.on('connection',function(socket){
    console.log("Hola")
    
    socket.on("statusUpdate", (data) => {
        console.log(data);
    });
});

Client (what I kind of need it to do):

var socket = io('http://localhost:3690');
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    console.log("Received");
    if (request[0] == "updateStatus") {
        console.log(request[1])
        socket.send(request[1])
    }
});

At this point, I have no idea what I can do in order to have the two communicate. Maybe the fact that the server will not be sending any requests to the client will help, but I still have no idea what I can do to solve this problem. If someone could help me and lead me towards the right direction, that would be amazing. Thank you for your time and help.

Batimius
  • 99
  • 3
  • 10
  • 1
    You don't show how you're trying to load the `socket.io-client` library into your chrome extension. The client library should be included in the extension package and declared in the manifest. This question may be helpful: https://stackoverflow.com/questions/37609783/chrome-extension-how-to-include-library-in-content-and-background-scripts-from – Jake Holzinger Apr 22 '21 at 17:55
  • Thank you for the reply. At first I used `require(socket.io)` and had the entire client module under a folder named node_modules. Just now I changed it so it is in a single script (which I found in this thread: https://stackoverflow.com/a/31112757/10328585) and also adds it into the manifest: `"background": {"scripts": ["background.js", "socket.io.js"]}`, but now it is just giving me a `io is not defined` error. @JakeHolzinger – Batimius Apr 22 '21 at 18:01
  • 1
    Are you loading the client library? There is a server library `socket.io` and a client library `socket.io-client`. – Jake Holzinger Apr 22 '21 at 18:16
  • I believe that is the client library, but I might be wrong. I want to make it clear that I am fairly new to JS and Node.js so I apologize for any misunderstandings. The client module seems to be a folder so I don't think I can import it via the manifest. Also, will I have to use it on a content script, or can I use it on a background script as well? – Batimius Apr 22 '21 at 18:19
  • A small update: I did import the client and am now running it via the content script, the only problem now is that the request keeps getting blocked by CORS policy and I have no idea how to get rid of it. – Batimius Apr 22 '21 at 18:36
  • 1
    You can download the version of the client you need from the socket.io CDN and package it into your extension. Or if you're building your extension in an automated fashion you can use the npm module `socket.io-client` to manage the dependency, the file you will want to use would be in `node_modules/socket.io-client/dist/`. – Jake Holzinger Apr 22 '21 at 18:37
  • 1
    CORS is a separate issue, it has to do with making a request to a different domain. Assume you're on `google.com` when you are using the extension, the extension will try to connect to `localhost`, these are different domains. The browser will block these requests unless you configure your node application to handle CORS correctly. I suggest you open a separate question if you get stuck on the CORS issue. – Jake Holzinger Apr 22 '21 at 18:40
  • That is probably why and if I do have an issue, I'll probably make a separate topic. My question now is, how would I be able to import the `socket.io.js` script in the `background.js` script? I was able to import it into the content script, but not the background one. My project outline looks like [this](https://prnt.sc/11vwlfu). I think that if we could figure this one out, we'll be able to solve the issue. Again, thank you for all of your help. @JakeHolzinger EDIT: Figured it out. – Batimius Apr 22 '21 at 18:56
  • I don't have an extension dev environment on hand to test it out, but I assume you would need to declare it in the `scripts` array. I assume the scripts are evaluated in order, so it should be declared before your background script. – Jake Holzinger Apr 22 '21 at 19:04

1 Answers1

2

I found the solution thanks to @JakeHolzinger. In short, I must make the package (or just take the one already created) a single script, in which I then have to import into the manifest.json. It is IMPORTANT that it is called BEFORE the background.js script as it will not import it otherwise. The manifest.json looks something like:

"background": {
    "scripts": ["socket.io.js", "background.js"]
}

From there, I can use the socket.io library freely and it will not be affected by the CORS policy if you are communicating with the client (localhost). The script now looks like this:

var socket = io('http://localhost:3690');
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    console.log("Received");
    if (request[0] == "updateStatus") {
        console.log(request[1])
        socket.send({"Title": Title, "Author": Author, "Album": Album})
    }
});

Very big thanks to @JakeHolzinger for helping me figure this out.

Batimius
  • 99
  • 3
  • 10
  • This solution for manifest.json worked for me! I also have socket.io working with a slightly different implementation. – Gary Vaughan Jr Jun 23 '22 at 22:40
  • @GaryVaughanJr I am trying to keep a connection open between browser extension and my server, but after a few seconds of inactivity, my brakcground script stops and the connection is lost. How do i keep the connection open? – Kraken Oct 17 '22 at 08:51