I'm running a development livereload server with gulp-server-livereload. This is the default task in gulpfile.js
var gulp = require('gulp');
var server = require('gulp-server-livereload');
gulp.task('default', function() {
gulp.src(basePath)
.pipe(server({
livereload: true,
host: domain,
port: 80,
}));
});
Then there's another task, gulp export, which requires this running web server. If I start another one it gives an error (because the ports 80 and 35729 are busy). So the logic I'm going for is this:
if gulp default is already running, dive right into nightmare.js tasks
else start a server and proceed to nightmare.js tasks
So my problem is I don't know a robust way to check if a gulp task is running.
Can I do that with some Gulp method? Or from the level of Node?
I wouldn't like to check open ports or webserver address as a proxy for "yes default task is running" if at all possible.
Can I do that with some Gulp method? Or from the level of Node? I wouldn't like to check open ports or webserver address as a proxy for "yes default task is running" if at all possible.
I have found no gulp way so far, so here is checking for ports busy. If they are it infers the server is running and proceeds with the export tasks, if not it starts a server.
var server = require('gulp-server-livereload');
gulp.task('export', function () {
var net = require('net');
var portFree = function(port, callback) {
var server = net.createServer(function(socket) {
socket.write('Echo server\r\n');
socket.pipe(socket);
});
server.listen(port, '127.0.0.1');
server.on('error', function (e) {
callback(false);
});
server.on('listening', function (e) {
server.close();
callback(true);
});
};
portFree(35729, function(returnValue) {
// If server isn't already running, start it.
if(returnValue) {
gulp.src(basePath)
.pipe(server({
livereload: true,
host: 'http://localhost'
}));
}
});
// Do the actual export tasks...
});
Related
I'm working on creating a WebApp using React and Websockets building it of from this example here: https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-live-data-visualization-in-web-apps
Locally everything is working fine. I have the React frontend code in a separate folder as well as the websocketserver code.
I'm trying to both into a single Azure Linux Web App (Basic tier not free) and starting it up with pm2 and this ecosystem.config.js:
module.exports = {
apps : [
{
name : "frontend",
script : "serve",
env: {
PM2_SERVE_PATH: './frontend/build',
PM2_SERVE_SPA: 'true',
}
},
{
name : "websocketserver",
script : "./websocketserver/server.js",
}
]
}
Both services are starting up correctly but the websocket connection is unable to connect.
The server in server.js looks like this:
const server = http.createServer();
const wss = new WebSocket.Server({ server });
wss.broadcast = (data) => {
if (wss.clients.size === 0) {
console.log(`No clients connected. Broadcasting over port ${server.address().port}`);
// console.log(`No clients connected. Broadcasting over port ${wss.options.port}`);
} else {
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
try {
console.log(`Broadcasting data ${data}`);
client.send(data);
} catch (e) {
console.error(e);
}
}
})
}
};
server.listen('8081', () => {
console.log('Listening on %d.', server.address().port);
});
If I use process.env.PORT || '3000' in server.listen(), then I get an EAINUSE error as it conflicts with the frontend 8080 port, so I handpicked 8081.
I have not found any useful article about this. Can anybody help and advice what to try?
Thanks!
I have followed the given documentation and able to get the desired result accordingly after changing the PORT to 8081.
Initially with PORT 3000, I got the below error.
I have changed the PORT to 8081 in server.js.
After changing the PORT you need to set IotHubConnectionString and EventHubConsumerGroup once again and run
npm install and npm start
Please follow the document correctly and check once again.
Set the PORT environment variable respective value in your App Service config, ref https://learn.microsoft.com/en-us/azure/app-service/configure-language-nodejs
I am using gulp-nodemon because of its most obvious of utilities.
Nodemon is a utility that will monitor for any changes
in your source and automatically restart your server.
But I am not understanding a practice which seems to be prevalent in express/node development.
I just started working with node and express but from what I understand:
app.js
var express = require('express'),
app = express(),
port = process.env.PORT || 8016;
app.get('/', function rootHndlr(req, res) {
/* body... */
res.send('welcome to my API!');
});
app.listen(port, function listenHndlr(){
console.log('Gulp is running my app on PORT ' + port);
});
The following is setting in the port to 8016 if not set.
port = process.env.PORT || 8016;
So now we binds and listens for connections on the specified host and port.
But then I see people configure in their gulp tasks the following to nodemon in their gulpfile.js
gulpfile.js
var gulp = require('gulp'),
nodemon = require('gulp-nodemon');
gulp.task('default', function() {
// content
nodemon({
script: 'app.js',
ext: 'js'
env: {
PORT: 8000
},
ignore: ['./node_modules/**']
}).
on('restart', function(){
consile.log('Restarting');
});
});
As you can one of the values in nodemon env: {PORT: 8000} Why set the port again?
Thanks!
People are using something like that as a fallback: port = process.env.PORT || 8016;
Your application should be flexible enough and by passing an env var to make it listen to another port. In general, this is the purpose of the env vars.
About your example, I suppose that there is a reason that the guy that wrote this gulpfile would like to make the app listen to port 8000. I would say that it is safe to change the value or to remove the PORT: 8000 as soon as you are 100% sure that there is no reason that the application needs to run on port 8000 (for example, it is behind a reverse proxy that forwards the traffic to port 8000).
I have an existing node app. My Node directory structure is setup like this:
./
node_modules/
src/
views/
index.html
...
server.js
test/
gulpfile.js
package.json
I can successfully start my app my running node ./src/server.js from the root shown above. Once started, I can visit "http://localhost:3000" in the browser and see the contents of index.html like I am expecting.
I want to speed up my development and I recently learned about browsersync. In an attempt to include it in my gulp process, I have the following:
var browserSync = require('browser-sync').create();
browserSync.init({
server: {
baseDir: './src/',
server: './src/server.js'
}
});
When I run gulp, I see the following in the command-line:
BS] Access URLs:
--------------------------------------
Local: http://localhost:3000
External: http://[ip address]:3000
--------------------------------------
UI: http://localhost:3001
UI External: http://[ip address]:3001
--------------------------------------
My browser is then opened and it attempts to load http://localhost:3000. At this point, I see the following error in the browser window:
Cannot GET /
What am I doing wrong? I can successfully visit http://localhost:3000 if I start my app using node ./src/server.js, however, its like its not running with BrowserSync. What am I doing wrong?
You already have a node server so i think what you need is Proxy.
And i would also suggest you to use nodemon for going one step ahead in your speed up development thing. It will automatically restart your node development server in case of any changes. So a sample gulpfile in your case(with nodemon) might look like
var gulp = require('gulp');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var nodemon = require('gulp-nodemon');
gulp.task('browser-sync', ['nodemon'], function() {
browserSync.init(null, {
proxy: "http://localhost:3700", // port of node server
});
});
gulp.task('default', ['browser-sync'], function () {
gulp.watch(["./src/views/*.html"], reload);
});
gulp.task('nodemon', function (cb) {
var callbackCalled = false;
return nodemon({script: './src/server.js'}).on('start', function () {
if (!callbackCalled) {
callbackCalled = true;
cb();
}
});
});
~
Why do you want to use the built-in server if you have your own in ./src/server.js ?
Check this, What server in browsersync does is create a static server for basic HTML/JS/CSS websites, so you might need to use the proxy feature as shown here.
This means that you need to run your server as normally and wrap it up in the proxy.
Using the express generator default folder structure with the start script in bin\www, and using the ejs template, this is how i modified my gulpfile.js :
var gulp = require('gulp');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var nodemon = require('gulp-nodemon');
gulp.task('browser-sync', ['nodemon'], function() {
browserSync.init(null, {
proxy: "http://localhost:8000", // port of node server
});
});
gulp.task('default', ['browser-sync'], function () {
gulp.watch(["./views/*.ejs"], reload);
});
gulp.task('nodemon', function (cb) {
var callbackCalled = false;
return nodemon({
script: './bin/www',
env: {
PORT: 8000
}}).on('start', function () {
if (!callbackCalled) {
callbackCalled = true;
cb();
}
});
});
Notice that am watching for any files that end in .ejs. I also got a problem when using nodemon with the port in use, so i added an env to pass the port as 8000,
env: { PORT: 8000 }
Since the tag grunt is missing from the question, here's a solution that works using only NPM (package.json):
"scripts": {
"start": "browser-sync start --serveStatic 'src' --serveStatic 'node_modules' --files 'src'"
}
Now all the <script> src attributes can be relative:
<script src="/stats-js/build/stats.min.js"></script>
I have a gulp task running with browser-sync,by default its running on port 3000 of node.js server.I want to change the default port to any other port like 3010.
var gulp = require('gulp'),
connect = require('gulp-connect'),
browserSync = require('browser-sync');
gulp.task('serve', [], function() {
browserSync(
{
server: "../ProviderPortal"
});
});
/*** 8. GULP TASKS **********/
gulp.task('default', ['serve']);
I am using:
browser-sync version-2.6.1
I tried configuring the gulp task like:
gulp.task('serve', [], function() {
browserSync(
{
ui: {
port: 8080
},
server: "../ProviderPortal"
});
});
But it didnot work.
Answer based on the documentation links (link1, link2).
You are using browser-sync version 2.0+, they have a different recommended syntax. Using that syntax your code could be like this:
// require the module as normal
var bs = require("browser-sync").create();
....
gulp.task('serve', [], function() {
// .init starts the server
bs.init({
server: "./app",
port: 3010
});
});
You specify required port directly in configuration object.
These are the versions of node and required modules I am using:
Node.js: 0.10.16
Websocket Library: einaros/ws ws#0.4.28
Proxy server: nodejitsu/node-http-proxy http-proxy#0.10.3
When I run the following program my console output looks like this, and doesn't move beyond this point:
$ node app.js
proxy: got upgrade, proxying web request
wss: got connection
Here's the code:
// app.js
// A simple proxying example
//
// Setup websocket server on port 19000
// Setup proxy on port 9000 to proxy to 19000
// Make a websocket request to 9000
//
var WebSocket = require('ws'),
WebSocketServer = WebSocket.Server,
proxy = require('http-proxy');
// goes in a loop sending messages to the server as soon as
// the servers are setup
var triggerClient = function() {
var ws = new WebSocket('ws://localhost:9090/');
ws.on('open', function() {
console.log('ws: connection open');
setInterval(function() {
ws.send("Hello");
}, 1000);
});
ws.on('message', function(data) {
console.log('ws: got ' + data);
});
}
// setup websocket server and a proxy
//
var go = function() {
// setup a websocket server on port 19000
//
var wss = new WebSocketServer({ port: 19000 });
wss.on('connection', function(ws) {
console.log('wss: got connection');
ws.on('message', function(data) {
console.log('wss: got ' + data);
ws.send('wss response: ' + data);
});
});
// setup a proxy server
var server = proxy.createServer(function (req, res, proxy) {
proxy.proxyRequest(req, res, {
host: 'localhost',
port: 19000
});
});
server.on('upgrade', function (req, socket, head) {
console.log('proxy: got upgrade, proxying web request');
server.proxy.proxyWebSocketRequest(req, socket, head, {
host: 'localhost',
port: 19000
});
});
server.listen(9090, triggerClient);
};
process.nextTick(go);
My problem eventually started when I was trying to use hipache, I then simplified things to node-http-proxy and then finally to this piece of code.
If you change the port the WebSocket client is connecting to from 9090 to 19000 (thereby bypassing the proxy), things seem to work fine.
Any suggestions, pointers, feedback would be greatly appreciated.
Thanks!
The core problem is that the master branch of node-http-proxy is only compatible with node <= 0.8.x (see https://github.com/nodejitsu/node-http-proxy#when-to-use-node-http-proxy): there's a tree that implements support for 0.10.x (see https://github.com/nodejitsu/node-http-proxy/tree/caronte) but it isn't the mainline branch and I haven't found any indication of when it will be merged in and available.