0

Sorry if my usage of server-related words is wrong, I'm new to this. I have two Express.js servers one on port 3000 and one on port 8000. The browser renders two different HTML files on these two ports. First I start the server on port 8000. As soon as I start the server on port 3000, I want to redirect the user viewing the site on port 8000 to a custom URL scheme to open an installed app (using "example://"). At the moment I console.log "received" on port 8000 as soon as the other server starts. How can I redirect the user to the URL "example://" so that the app opens?

This is my code for server one (port 3000):

import express, { response } from "express";
import fetch from "node-fetch";
import * as path from 'path';
import { fileURLToPath } from "url";


const touchpointApp = express();
const port = 3000;
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

touchpointApp.get('/', (req, res) => {
    res.sendFile('/index.html', { root: __dirname });
});

touchpointApp.listen(port, () => {
    console.log('Running on Port 3000');
    fetch("http://192.168.2.127:8000/launch").then(res => {console.log("Success")});
    
})

And this is my code for server two (port 8000):

const { response } = require('express');
const express = require('express');
const open = require('open');
const router = express.Router();
const path = require('path');
const smartMirror = express();


router.get('/', function(req, res){
    res.sendFile(path.join(__dirname + '/index.html'));
});

smartMirror.use('/', router);
smartMirror.listen(process.env.port || 8000);

console.log('Running on Port 8000');


smartMirror.get("/launch", (req, res) => {
    console.log("Received");
    res.status(200);
})

The code is currently Frankenstein's monster because of the previous tests. I'm using NodeJS to start the servers.

Oliver
  • 25
  • 1
  • 6

2 Answers2

0

This is my understanding of your intent:

  1. User in browser visits http://somehost:8000/someUrl and gets a page
  2. You start server on port 3000, the 8000 server somehow detects this
  3. Subsequent requests to http://somehost:8000/someUrl are now redirected to http://somehost:3000/differentUrl and hence the user is now navigating among pages in the 3000 server. Note that the 8000 server is telling the browser: "don't look here, go to the 3000 server for your answer".

If that is your intent then you can send a redirect by

smartMirror.get("/launch", (req, res) => {
    res.redirect("http://somehost:3000/differentUrl");
})

So you might have code such as

smartMirror.get("/launch", (req, res) => {
    // assuming that you can figure out that the 3000 server is running
    if ( the3000ServerIsRunning ) {
         let originalURL = req.originalUrl;
         
         let redirectedURL = // code here to figure out the new URL
         res.redirect("http://somehost:3000" + redirectedURL);
    else {
          // send a local respons
    }
    
})
djna
  • 54,992
  • 14
  • 74
  • 117
  • What would I need to write in `let redirectedURL`? Something like `originalUrl.replace("/launch", "");`? – Oliver Mar 31 '22 at 09:02
  • All depends on the relationship between the user's original URL and the redirected URL. You can perform any string manipulation you wish (such as replace) or simply hard-code the URL. – djna Mar 31 '22 at 09:08
  • Got it. But why do I need to add the "somehost:3000" address when I redirect them? I don't know what I'm missing here but shouldn't it just redirect to "example://"? I can only launch the app by typing "example://" and nothing more – Oliver Mar 31 '22 at 09:24
  • I basically would need to do something like `window.location.replace("example://")` but that doesn't work because it's running on a server – Oliver Mar 31 '22 at 09:31
  • the redirect is information sent to the browser. The browser asks for a page from the 8000 server and the 8000 server says "no", instead request another page from the 3000 server. From that point on the browser is requesting directly from the 3000 server, the 8000 server is not involved. – djna Mar 31 '22 at 14:31
  • You may be thinking of treating the 8000 server as a "proxy" where the 8000 server itself fetches from the 3000 server and passes the result back to the browser, but that is not what I think you asked for. You may need to clarify the question. – djna Mar 31 '22 at 14:32
0

I think you can do it with the location http response header.

res.location('example://...')
Clem
  • 2,150
  • 15
  • 17
  • That doesn't do anything sadly. No errors, nothing. What I'm doing at the moment is, I have a `let received = false`and as soon as the server on port 3000 starts, this gets set to `true`. That works without a problem. And then I say `if(received == true){ redirect to my custom URL scheme }`. In the if-statement I basically need to say `window.location.replace("example://")`but that doesn't work because it's on a server (I think) – Oliver Mar 31 '22 at 09:41
  • code such as window.location.replace would run in JavaScript in the browser. Is that what you intend? Please clarify which code you expect to run in the browser and which on the server. – djna Mar 31 '22 at 14:35
  • @djna So, the server on port 8000 receives something from the server on Port 3000 as soon as the Port 3000 one starts. In the code of server 8000, I then set `let received = false` to `true`. As soon as `received == true`I want to do something like `window.location.replace("example://")`. I can't clarify it more than that because I don't know what to do exactly. I just know that I want to open the app with "example://", like if I typed "example://" in the address bar of the browser – Oliver Apr 02 '22 at 09:33
  • I should add that I'm not experienced in coding. I code once every semester for university projects and I only know the basics. I don't want to waste your time but I basically need the exact code I can use. I understand what you mean and understand the logic behind it, but I don't know how to write it. – Oliver Apr 02 '22 at 09:42
  • As I understand it you're asking for something to happen in the browser (window replace) when the server gets new information. This can't be simply achieved, once a browser has rendered a page it does not have any simple way to get additional information from the server. There are ways to achieve this effect, but they all require quite a bit of coding. If it was a one-liner I;d be happy to share, but writing serious code is beyond my understanding of StackOverflow's remit. – djna Apr 02 '22 at 16:00
  • 1
    @djna Hm okay but one more thought, I don’t know if this would work: Let’s say I create a second script that gets referenced in the HTML that gets rendered on port 8000. Let’s call it startApp.js. In my server.js the received variable gets set to true. I export the variable using module.exports and import it into startApp.js. In startApp.js I do something that checks every few seconds or so, if the state of received changed and if it is true, I do window.location.replace. Would that work in theory? Because then it happens in the browser, doesn’t it? – Oliver Apr 03 '22 at 09:07
  • Yes, indeed, this is the kind of solution I was referring to. In general, you need code in browser cooperating with server. There are cleverer approaches where server can "push" information to browser using WebSockets, but that's even more code to write. Your "polling" approach is feasible and I think simplest to achieve a browser update when server changes at some indeterminate time. – djna Apr 04 '22 at 04:23