I use php(laravel 5.8) to broadcast, and I use laravel-echo-server, it's work. But!!! recent I need to something by my self. And I write a socket service by ndoejs. This is my code
const jwt = require('jsonwebtoken');
const server = require('http').Server();
const io = require('socket.io')(server);
...
// ==== The question is here =====================
const Redis = require('ioredis');
const redis = new Redis({
port: REDIS_PORT,
host: REDIS_HOST,
password: REDIS_PASSWORD
});
redis.psubscribe('myTestChannel.*');
redis.on('pmessage', function(pattern, channel, message) {
console.log(channel, message);
const object_message = JSON.parse(message);
io.sockets.emit(channel, object_message.data);
});
// ==== The question is here =====================
io.sockets.use(function (socket, next) {
if (socket.handshake.query && socket.handshake.query.token){
// auth
} else {
next(new Error('Authentication error'));
}
}).on('connection', function(socket) {
console.log('==========connection============');
console.log('Socket Connect with ID: ' + socket.id);
socket.on('join', (data) => {
... do something
});
socket.on('disconnect', () => {
... do something
})
});
server.listen(LISTEN_PORT, function () {
console.log(`Start listen ${LISTEN_PORT} port`);
});
It's work, but running a long time, my php get a error message, phpredis read error on connection. I'm not sure the real reason. But I guess is about my socket, because I use laravel-echo-server is great.
I'm not sure my redis.psubscribe's position is right? Maybe this cause a long time connection and cause php read error on connection?
I should move the redis.psubscribe into on('connection') and unsubscribe when disconnection?
I want to know the redis.psubscribe is the main cause the problem? Thanks your help.
I am tried to use socket io on the live server and I got this error.
polling-xhr.js:264 GET http://sub.domain.com:3000/socket.io/?EIO=3&transport=polling&t=MFUVMS5 net::ERR_TIMED_OUT
But on my local server, the files worked perfectly. I am working with socket.io and PHP.
Here are my codes:
server.js
var socket = require('./node_modules/socket.io');
var express = require('./node_modules/express');
var app = express();
var server = require('http').createServer(app);
var io = socket.listen(server);
var port = process.env.PORT || 3000;
// server active console view
server.listen(port, function () {
console.log('Server listening at port %d', port);
});
io.on('connection', function (socket) {
// show new added online user
socket.on('now_online', function (data) {
io.sockets.emit('now_online',{
id: data.id,
name: data.name
});
});
});
main.js
var socket = io.connect('http://'+window.location.hostname+':3000');
socket.on('new_online_user', function (data) {
if (login_id != data.online_user) {
$('#contacts-list .contact[data-chat='+data.online_user+']'+' .contact-status').addClass('online');
}
});
package.json
{
"private": true,
"dependencies": {
"gulp": "^3.9.1",
"express": "^4.16.2",
"socket.io": "^2.0.4"
}
}
I was searching in google and StackOverflow about this issue but those solved didn't work for me.
Thanks so much.
Try connecting using only domain without http like:
var socket = io.connect(window.location.hostname+':3000', {transports: ["websocket", "xhr-polling", "htmlfile", "jsonp-polling"]});
It will automatically become ws://sub.domain.com:3000/socket.io/?EIO=3&transport=polling&t=MFUVMS5. I'm using similar to this and working fine.
I'm trying to access a mysql database using node.js. I simply run the following command in cmd prompt:
C:\rest-server> node bin/www
and it displays this message:
Express server listening in port 80
and I've the .js file as follows which the localhost access at port 80:
var express = require('express');
var router = express.Router();
var async = require('async');
var util = require('../utils/util');
var db = require('../utils/database');
var connection = db.connection();
router.get('/login', function (req, res) {
if (req.session.manager) {
return res.redirect('/');
}
if (req.query.tip == 'error') {
var tip = 'username or password incorrect!';
} else {
var tip = null;
}
res.render('login', { tip: tip });
});
router.post('/login', function (req, res) {
var username = req.body.username;
var password = req.body.password;
var sql = 'SELECT * FROM restaurant_accounts WHERE ra_name=?';
connection.query(sql, [username], function (err, result) {
if (err) throw err;
if (result.length == 0) {
return res.redirect('/manager/login?tip=error');
}
var account = result[0];
if (!util.checkHash(password, account.ra_password)) {
return res.redirect('/manager/login?tip=error');
}
connection.query('SELECT * FROM restaurants WHERE rest_owner_id=?', [account.ra_id], function (err, result) {
if (err) throw err;
var restaurant = result[0];
req.session.manager = {
id: account.ra_id,
name: account.ra_name,
rest_id: restaurant.rest_id,
rest_name: restaurant.rest_name
};
res.redirect('/');
});
});
});
router.get('/logout', function (req, res) {
req.session.destroy();
res.redirect('/manager/login');
});
module.exports = router;
When I type localhost:80 on my browser it displays the following screen:
But ofcourse since the database is not linked, I can't get past this step and it shows the "localhost refused to connect" error!
I already have a .sql database with necessary tables created. How do I link these two so I can login from the login page?
EDIT: database.js
var mysql = require('mysql');
var c = mysql.createConnection({
host : 'localhost',
user : 'bjtu',
password : 'bjtu',
database : 'restaurant'
});
// enable error logging for each connection query
c.on('error', function(err) {
console.log(err.code); // example : 'ER_BAD_DB_ERROR'
});
exports.connection = function() {
return c;
};
CONSOLE ERROR FOR SAMPLE.JS
if (err) throw err;
^
Error: ER_ACCESS_DENIED_ERROR: Access denied for user 'me'#'localhost' (using password: YES)
at Handshake.Sequence._packetToError (C:\Mrestro\RESTaurant_backend-master\rest-server\node_modules\mysql\lib\protocol\sequences\Sequence.js:51:14)
at Handshake.ErrorPacket (C:\Mrestro\RESTaurant_backend-master\rest-server\node_modules\mysql\lib\protocol\sequences\Handshake.js:103:18)
at Protocol._parsePacket (C:\Mrestro\RESTaurant_backend-master\rest-server\node_modules\mysql\lib\protocol\Protocol.js:280:23)
at Parser.write (C:\Mrestro\RESTaurant_backend-master\rest-server\node_modules\mysql\lib\protocol\Parser.js:74:12)
at Protocol.write (C:\Mrestro\RESTaurant_backend-master\rest-server\node_modules\mysql\lib\protocol\Protocol.js:39:16)
at Socket.<anonymous> (C:\Mrestro\RESTaurant_backend-master\rest-server\node_modules\mysql\lib\Connection.js:109:28)
at emitOne (events.js:77:13)
at Socket.emit (events.js:169:7)
at readableAddChunk (_stream_readable.js:153:18)
at Socket.Readable.push (_stream_readable.js:111:10)
--------------------
at Protocol._enqueue (C:\Mrestro\RESTaurant_backend-master\rest-server\node_modules\mysql\lib\protocol\Protocol.js:141:48)
at Protocol.handshake (C:\Mrestro\RESTaurant_backend-master\rest-server\node_modules\mysql\lib\protocol\Protocol.js:52:41)
at Connection.connect (C:\Mrestro\RESTaurant_backend-master\rest-server\node_modules\mysql\lib\Connection.js:136:18)
at Object.<anonymous> (C:\Mrestro\RESTaurant_backend-master\rest-server\utils\sample.js:9:12)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
The npm module mysql should do the trick.
Basic connect would look like this:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
if (err) throw err;
console.log('The solution is: ', rows[0].solution);
});
connection.end();
Probably soon you would like to have a look at MongoDB. Which you can connect to using module mongoose, for example.
Update:
Try to set port to your connection object in database.js. Like this:
var mysql = require('mysql');
var c = mysql.createConnection({
host : 'localhost',
user : 'bjtu',
password : 'bjtu',
database : 'restaurant',
port : 90
});
// enable error logging for each connection query
c.on('error', function(err) {
console.log(err.code); // example : 'ER_BAD_DB_ERROR'
});
exports.connection = function() {
return c;
};
The default port is 3306, which doesnt look like your case :)
And I suggest you to look into mysql pools.
I am writing an application with node and laravel. I am running small laravel local server which resolves to http://localhost:8000. i am also running a node server on localhost:3000. Then trying to call the first server from the second. Here is the NodeJs code:
var restify = require('restify');
var server = restify.createServer();
server.listen(3000, function() {
console.log('%s listening at %s', server.name, server.url);
});
Here is where I make the http request:
var http = require('http');
module.exports = {
call: function (host, path) {
var options = {
host: host,
path: path,
port: 8000,
method: 'GET'
};
callback = function(response) {
var str = '';
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
return str;
});
}
http.request(options, callback).end();
}
}
This is the actual call I am making:
httpCaller.call('http://localhost', '/fire');
I get the following response on the command line:
Error: getaddrinfo ENOTFOUND http://localhost http://localhost:8000
at errnoException (dns.js:26:10)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:77:26)
I tried removing http:// and just calling local host, and got the following:
Error: connect ECONNREFUSED 127.0.0.1:8000
at Object.exports._errnoException (util.js:890:11)
at exports._exceptionWithHostPort (util.js:913:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1057:14)
How can I do this?
Try using the http.get function?
http.get('http://localhost:8000/fire', (res) => {
console.log(`Got response: ${res.statusCode}`);
// consume response body
res.resume();
}).on('error', (e) => {
console.log(`Got error: ${e.message}`);
});
I have a node.js server opening 8000 port. It is a chat server.
I have another PHP server and I use proxy + virtual host so when I go www.phpserver.com/chat It proxies to the node.js server. I did this so I can use ajax to call the node.js server.
Right now, everything works fine when i run the node.js server, however, after a while (a random time frame, not necessarily long or short), the PHP server will crush because it gets an EOF from the node.js server and it's just stuck there until I stop/restart the node.js server.
The error I get is(from php error log):
(70014)End of file found: proxy: error reading status line from remote
server nodeserver.com:8000, referer: https://www.phpserver.com
I asked some professionals and they said it's because of the PHP server sends the request to the node.js server successfully and receives an EOF or fails to receive any response. I don't understand how to fix it tho. What should I do so even the node.js server crushes, it won't crush the PHP server? Should I get rid of the proxy+ajax and starts to use socket.io?
Please advise.
Thank you!
Below is some node codes.
From middleware:
this.events.addListener('update', o_.bind(function(package) {
if(this.clear != 0){
delete this.sessions[this.clear];
}
var _package = package.toJSON();
if(package.type == 'status' && package.status == 'offline') {
var sids = Object.keys(this.sessions), sid, sess;
for(sid in this.sessions) {
sess = this.sessions[sid];
if(sess.data('username') == package.username) {
if(sess.listeners.length)
sess.send(200, {type: 'goodbye'});
delete this.sessions[sid];
break;
}
}
}
}, this));
};
Hub.prototype.destroy = function(sid, fn) {
this.set(sid, null, fn);
};
Hub.prototype.reap = function(ms) {
var threshold = +new Date - ms,
sids = Object.keys(this.sessions);
for(var i = 0, len = sids.length; i < len; ++i) {
var sid = sids[i], sess = this.sessions[sid];
if(sess.lastAccess < threshold) {
this.events.emit('update', new packages.Offline(sess.data('username')));
}
}
};
Hub.prototype.get = function(req, fn) {
if(this.sessions[req.sessionID]) {
fn(null, this.sessions[req.sessionID]);
} else {
this.auth.authenticate(req, o_.bind(function(data) {
if(data) {
var session = new User(req.sessionID, data);
this.set(req.sessionID, session);
this.auth.friends(req, data, o_.bind(function(friends) {
var friends_copy = friends.slice();
o_.values(this.sessions).filter(function(friend) {
return ~friends.indexOf(friend.data('username'));
}).forEach(function(friend) {
var username = friend.data('username');
friends_copy[friends_copy.indexOf(username)] =
[username, friend.status()];
}, this);
session._friends(friends_copy);
console.log("refreshed");
session.events.addListener('status',
o_.bind(function(value, message) {
this.events.emit(
'update',
new packages.Status(session.data('username'),
value,
message)
);
}, this));
this.events.addListener('update',
o_.bind(session.receivedUpdate, session));
this.set(req.sessionID, session);
fn(null, session);
}, this));
} else {
fn();
}
}, this));
}
};
From app.js
#!/usr/bin/env node
var sys = require('sys'),
express = require('express'),
packages = require('./libs/packages'),
fs = require('fs'),
o_ = require('./libs/utils'),
https = require('https');
o_.merge(global, require('./settings'));
try { o_.merge(global, require('./settings.local')); } catch(e) {}
try {
var daemon = require('./libs/daemon/daemon'),
start = function() {
daemon.init({
lock: PID_FILE,
stdin: '/dev/null',
stdout: LOG_FILE,
stderr: LOG_FILE,
umask: 0,
chroot: null,
chdir: '.'
});
},
stop = function() {
process.kill(parseInt(require('fs').readFileSync(PID_FILE)));
};
switch(process.argv[2]) {
case 'stop':
stop();
process.exit(0);
break;
case 'start':
if(process.argv[3])
process.env.EXPRESS_ENV = process.argv[3];
start();
break;
case 'restart':
stop();
start();
process.exit(0);
break;
case 'help':
sys.puts('Usage: node app.js [start|stop|restart]');
process.exit(0);
break;
}
} catch(e) {
sys.puts('Daemon library not found! Please compile ' +
'./libs/daemon/daemon.node if you would like to use it.');
}
var options = {
key: fs.readFileSync('/home/ec2-user/key.pem'),
cert: fs.readFileSync('/home/ec2-user/cert.pem'),
ca: fs.readFileSync('/home/ec2-user/ca.pem'),
};
var app = express();
//app.set('env', 'development');
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(require('./middleware/im')({
maxAge: 30 * 1000,
reapInterval: 20 * 1000,
authentication: require('./libs/authentication/' + AUTH_LIBRARY)
}));
app.set('root', __dirname);
if ('development' == app.get('env')) {
app.set('view engine', 'jade');
app.set('views', __dirname + '/dev/views');
app.stack.unshift({
route: '/dev',
handle: function(req, res, next) {
req.dev = true;
next();
}
});
app.use(express.logger());
require('./dev/app')('/dev', app);
app.use(express.static(
require('path').join(__dirname, '../client')));
app.use(express.errorHandler({dumpExceptions: true, showStack: true}));
}
//app.listen(APP_PORT, APP_HOST);
// Listener endpoint; handled in middleware
app.get('/listen', function(){});
app.post('/message', function(req, res) {
res.find(req.body['to'], function(user) {
if(!user)
return res.send(new packages.Error('not online'));
res.message(user, new packages.Message(
req.session.data('username'),
req.body.body
));
});
});
app.post('/message/typing', function(req, res) {
if(~packages.TYPING_STATES.indexOf('typing' + req.body['state'])) {
res.find(req.body['to'], function(user) {
if(user) {
res.message(user, new packages.Status(
req.session.data('username'),
'typing' + req.body.state
));
}
// Typing updates do not receive confirmations,
// as they are not important enough.
res.send('');
});
} else {
res.send(new packages.Error('invalid state'));
}
});
app.post('/status', function(req, res) {
if(~packages.STATUSES.indexOf(req.body['status'])) {
res.status(req.body.status, req.body.message);
res.send(new packages.Success('status updated'));
} else {
res.send(new packages.Error('invalid status'));
}
});
app.post('/online', function(req, res) {
var d = new Date();
var n = d.getTime() + 30;
req.sessionID.expires = n;
res.status(req.body.status, 'available');
});
app.post('/signoff', function(req, res) {
res.signOff();
res.send(new packages.Success('goodbye'));
});
app.use(function(err, req, res, next){
console.error(err.stack);
res.send(500, 'Error on the node/express server.');
});
https.createServer(options, app).listen(8000);
I can't help you answer your question but I can try to point you in a right direction.
I'm currently working on a Node JS server myself, and I found very useful to have a logger setup.
There are a few of them, but my favorite is Winston so far.
Reference: https://github.com/flatiron/winston
To install Winston for your Node JS server (seems you have already installed a few modules):
npm install winston
Then I have logger module setup as (logger.js):
/**
* Usage:
* - logger.info('sample text');
* - logger.warn('sample text');
* - logger.error('sample text');
*/
// Load modules
var winston = require('winston');
// Create custom logger
var logger = new (winston.Logger)({
transports: [
new (winston.transports.Console)({ json: false, timestamp: true }),
new winston.transports.File({ filename: __dirname + '/debug.log', json: false })
],
exceptionHandlers: [
new (winston.transports.Console)({ json: false, timestamp: true }),
new winston.transports.File({ filename: __dirname + '/exceptions.log', json: false })
],
exitOnError: false
});
// Export logger
module.exports = logger;
Finally I load in Winston logger module into my server scripts by:
var logger = require('./logger');
It will automatically log any exceptions into exceptions.log on your Node JS server location. It helped me out a lot to catch exceptions I haven't noticed before within Node JS unrelated to PHP.
P.S. Also check out socket.io, that may simplify what you are trying to do.