Roots Discourse

Localhost unexpectedly closed the connection


#1

I am experiencing a strange issue when I run

“Yarn Start”

everything compiles and runs properly but when the browser opens

up I get the following error message and it looks as Sage is trying to

initiate a secure connection and the site doesn’t load.

But wait there’s more

If I open a new terminal window and run

“Yarn Start”

again, a new browser sync session is initiated on port :3002 and the site works fine!

Anyone have this problem as well?


#2

Hey @herbg9900,

Re the port change, it sounds like you already have something running on port 3000 and so Browsersync isn’t able to use the port to proxy your dev site. Browsersync will automatically increment the port number if it detects that the one specified by its config is in use.

Check your running processes to see if you already have a Browsersync session going (it could be lingering from a shell that you closed)–it will probably just show up as “node” in the list of processes. On Linux/Mac/WSL, you can run ps -e | grep node.

That’s presumably also why the first session can’t connect to your site–the port is already bound to something else. It’s strange that it takes two runs for Browsersync to figure that out and adapt, though. I might head over to that project and see if you can find any similar reports.


#3

Hi @mmirus,

Thanks for the reply. I am not sure what is going on…

Check your running processes to see if you already have a Browsersync session going (it could be lingering from a shell that you closed)–it will probably just show up as “node” in the list of processes. On Linux/Mac/WSL, you can run ps -e | grep node.

There was no other process besides some apps I have on the computer, e.g. CC, Slack etc.

I turned on BrowserSync Debug mode and here is the log. Is there something in here that is relevant to why this is happening?

[BS] [debug] -> Starting Step: Finding an empty port
[BS] [debug] Found a free port: 3000
[BS] [debug] Setting Option: port - 3000
[BS] [debug] +  Step Complete: Finding an empty port
[BS] [debug] -> Starting Step: Getting an extra port for Proxy
[BS] [debug] +  Step Complete: Getting an extra port for Proxy
[BS] [debug] -> Starting Step: Checking online status
[BS] [debug] Resolved www.google.com, setting online: true
[BS] [debug] Setting Option: online - true
[BS] [debug] +  Step Complete: Checking online status
[BS] [debug] -> Starting Step: Resolve user plugins from options
[BS] [debug] +  Step Complete: Resolve user plugins from options
[BS] [debug] -> Starting Step: Set Urls and other options that rely on port/online status
[BS] [debug] Setting multiple Options
[BS] [debug] +  Step Complete: Set Urls and other options that rely on port/online status
[BS] [debug] -> Starting Step: Setting Internal Events
[BS] [debug] +  Step Complete: Setting Internal Events
[BS] [debug] -> Starting Step: Setting file watchers
[BS] [debug] +  Step Complete: Setting file watchers
[BS] [debug] -> Starting Step: Merging middlewares from core + plugins
[BS] [debug] Setting Option: middleware - List [ function webpackDevMiddleware(req, res, next) {
    function goNext() {
      if(!context.options.serverSideRender) return next();
      return new Promise(function(resolve) {
        shared.ready(function() {
          res.locals.webpackStats = context.webpackStats;
          resolve(next());
        }, req);
      });
    }

    if(req.method !== "GET") {
      return goNext();
    }

    var filename = getFilenameFromUrl(context.options.publicPath, context.compiler, req.url);
    if(filename === false) return goNext();

    return new Promise(function(resolve) {
      shared.handleRequest(filename, processRequest, req);
      function processRequest() {
        try {
          var stat = context.fs.statSync(filename);
          if(!stat.isFile()) {
            if(stat.isDirectory()) {
              var index = context.options.index;

              if(index === undefined || index === true) {
                index = "index.html";
              } else if(!index) {
                throw "next";
              }

              filename = pathJoin(filename, index);
              stat = context.fs.statSync(filename);
              if(!stat.isFile()) throw "next";
            } else {
              throw "next";
            }
          }
        } catch(e) {
          return resolve(goNext());
        }

        // server content
        var content = context.fs.readFileSync(filename);
        content = shared.handleRangeHeaders(content, req, res);
        var contentType = mime.lookup(filename);
        // do not add charset to WebAssembly files, otherwise compileStreaming will fail in the client
        if(!/\.wasm$/.test(filename)) {
          contentType += "; charset=UTF-8";
        }
        res.setHeader("Content-Type", contentType);
        res.setHeader("Content-Length", content.length);
        if(context.options.headers) {
          for(var name in context.options.headers) {
            res.setHeader(name, context.options.headers[name]);
          }
        }
        // Express automatically sets the statusCode to 200, but not all servers do (Koa).
        res.statusCode = res.statusCode || 200;
        if(res.send) res.send(content);
        else res.end(content);
        resolve();
      }
    });
  }, function (req, res, next) {
    if (!pathMatch(req.url, opts.path)) return next();
    eventStream.handler(req, res);
    if (latestStats) {
      // Explicitly not passing in `log` fn as we don't want to log again on
      // the server
      publishStats("sync", latestStats, eventStream);
    }
  } ]
[BS] [debug] +  Step Complete: Merging middlewares from core + plugins
[BS] [debug] -> Starting Step: Starting the Server
[BS] [debug] Proxy running, proxing: http://---------.test
[BS] [debug] Running mode: PROXY
[BS] [debug] +  Step Complete: Starting the Server
[BS] [debug] -> Starting Step: Starting the HTTPS Tunnel
[BS] [debug] +  Step Complete: Starting the HTTPS Tunnel
[BS] [debug] -> Starting Step: Starting the web-socket server
[BS] [debug] Setting Option: clientEvents - List [ "scroll", "scroll:element", "input:text", "input:toggles", "form:submit", "form:reset", "click" ]
[BS] [debug] +  Step Complete: Starting the web-socket server
[BS] [debug] -> Starting Step: Starting the UI
[BS] [debug] Setting Option: session - 1540187522059
[BS] [UI] Starting Step: Setting default plugins
[BS] [UI] Step Complete: Setting default plugins
[BS] [UI] Starting Step: Finding a free port
[BS] [UI] Step Complete: Finding a free port
[BS] [UI] Starting Step: Setting options also relevant to UI from BS
[BS] [UI] Step Complete: Setting options also relevant to UI from BS
[BS] [UI] Starting Step: Setting available URLS for UI
[BS] [debug] Getting option via path: urls
[BS] [UI] Step Complete: Setting available URLS for UI
[BS] [UI] Starting Step: Starting the Control Panel Server
[BS] [UI] Using port 3001
[BS] [UI] Step Complete: Starting the Control Panel Server
[BS] [UI] Starting Step: Add element events
[BS] [UI] Step Complete: Add element events
[BS] [UI] Starting Step: Registering default plugins
[BS] [UI] Step Complete: Registering default plugins
[BS] [UI] Starting Step: Add options setting event
[BS] [UI] Step Complete: Add options setting event
[BS] [debug] +  Step Complete: Starting the UI
[BS] [debug] -> Starting Step: Merge UI settings
[BS] [debug] Setting Option: urls - Map { "local": "http://localhost:3000", "external": "http://192.168.15.13:3000", "ui": "http://localhost:3001", "ui-external": "http://192.168.15.13:3001" }
[BS] [debug] +  Step Complete: Merge UI settings
[BS] [debug] -> Starting Step: Init user plugins
[BS] [HTML Injector] Running...
[BS] [debug] Setting Option: userPlugins - [object Object]
[BS] [debug] +  Step Complete: Init user plugins
[Browsersync] Proxying: http://---------.test
[Browsersync] Access URLs:
 --------------------------------------
       Local: http://localhost:3000
    External: http://192.168.15.13:3000
 --------------------------------------
          UI: http://localhost:3001
 UI External: http://192.168.15.13:3001
 --------------------------------------
[Browsersync] Watching files...


 DONE  Compiled successfully in 1129ms

#4
  1. Can you share your config.json file?
  2. Does it work when you try http://localhost:3000 instead of https://localhost:3000?

From your description / the info provided, it looks like it might be trying to load it over SSL when your site isn’t set up for that.


#5
  1. Here is the config.

     {
    

    “entry”: {
    “main”: [
    “./scripts/main.js”,
    “./styles/main.scss”
    ],
    “customizer”: [
    “./scripts/customizer.js”
    ]
    },
    “publicPath”: “/wp-content/themes/ais-act”,
    “devUrl”: “http://-------.test”,
    “proxyUrl”: “http://localhost:3000”,
    “cacheBusting”: “[name]_[hash:8]”,
    “watch”: [
    “app//*.php",
    "config/
    /.php",
    "resources/views/**/
    .php”
    ]
    }

  2. When I try with http, it just redirects me back to https://localhost:3000.


#6

You may be having an HSTS problem: SSL on Local Mistake || Can’t fix


#7

Brilliant! that was the issue.

Just to expand on that for anyone who comes across this.

chrome://net-internals/#hsts > sockets > flush socket pools

Thank you for your help @alwaysblank && @mmirus


#8

I’m back, unfortunately the solution was short-lived and it has defaulted back to the original issue…

Anymore suggestions @alwaysblank?

Thanks,


#9

If the site is appearing again in the HSTS database, then you (or some other process on your computer) is still visiting localhost at https. You need to find out what that is, and tell it to stop.