Socket IO v1.4.5 disconnect issue - socket.io

I'm working on socket room and i try to disconnect from client side when i refresh the page, the problem is in console i receive message that socket id is disconnected, and another socket id generated but the old socket still active
here is my code in client side :
var roomSocket = io.connect("http://mysitehere.com:5001", {'forceNew': true});
var room = port;
roomSocket.on('connect', function () {
roomSocket.emit('starting', room);
console.log('emit connection to room');
});
roomSocket.on('connected', function () {
console.log('connected user');
});
roomSocket.on('message', function (data) {
console.log('Incoming message:' + data);
});
$(document).unload(function () {
roomSocket.disconnect();
});
my code in server js
socket.on('disconnect', function (data) {
console.log('------------------------------------');
console.log("DISCONNECTION : " + socket.id);
console.log('------------------------------------');
});
and the result :

Related

Socket.io transport close and ping timeout error

Socket client is getting disconnected either due to transport close or pingtimeout error. And it happens randomly. Sometime the socket client is stable for couple of hours and after that is start disconnecting randomly.Can anyone help me finding the issue.
Socket-Client version : 2.1.0
Socket Server version : 2.1.0,
Client Code
const socket = require('socket.io-client')
let url = 'http://localhost:5050'
let clientSocket = socket.connect(url, {
reconnection: true,
forceNew: true,
secure: true
})
clientSocket.on("connect", function (data) {
// console.log(clientSocket)
console.log("connection established");
});
clientSocket.on("event", function(data) {
console.log(data)
})
Server Code
const socketio = require('socket.io');
this.io = socketio.listen(this.server,
{
'pingInterval': PING_INTERVAL,
'pingTimeout': PING_TIMEOUT
});
this.io.on('connection', function (socket) {
// const consumer = new ConsumerGroup(options, topic);
// reading data from add event and sending back the same data
console.log('Connected', socket.id);
const token = socket.handshake.query.token;
socket.on('disconnect', function () {
console.log(socket.id + ' -> Disconnected');
});
consumer.on('ready', function (message) {
console.log('Ready');
});
consumer.on('message', function (message) {
// sending message on socket when we recieve the message from kafka\
socket.emit('alarm', message);
});
consumer.on('error', function (err) {
console.log('error', err);
});
});

Reconnect stomp when disconnected

I am using the following code to create/subscribe to a topic and handle the messages. Sometimes the connection gets lost and the error says:
Whoops! The connection was lost...
I would like to know if there is a way to reconnect it. Is it possible in the error callback or define the whole code in a method and call it recursively in error callback ?
$(document).ready(function () {
........
...............
try {
var socket = new SockJS("${createLink(uri: '/stomp')}");
var client = Stomp.over(socket);
client.connect({}, function () {
client.subscribe("/topic/${userInstance?.username}",
function (message) {
............
....................
});
});
} catch (error) {
console.log("ERROR: " + error.toString());
}
});
I managed to do it using failure callback and connect again. It will keep trying as long as it will fail.
This is what I am using in a Polymer element:
ready: function() {
this.connectWs();
},
connectWs: function() {
this.socket = new WebSocket(this.socketUrl);
this.stompClient = Stomp.over(this.socket);
this.stompClient.debug = null;
this.stompClient.connect({},
function(frame) {
// Connection OK
}.bind(this),
function(e) {
console.error(e, "Reconnecting WS", this.socketUrl);
window.setTimeout(function() {
this.connectWs();
}.bind(this), 2500);
}.bind(this)
);
},

Difference between io.on and socket.on in Socket.io?

I am confused on what the 'socket' parameter is that is passed with the function (In 'The enigma' section). Then the parameter gets used 'socket.on'. What is the difference between io.on and socket.on?
The following code is slightly adapted from the Socket.io chat application example.
Variables
var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app)
var io = require('socket.io').listen(server);
The enigma
io.on('connection', function (socket) {
console.log('user connected');
socket.on('message', function(msg) {
console.log('message: ' + msg);
io.emit('message', msg);
})
});
Start server
server.listen(3000, function() {
console.log('server is running');
});
index.jade
body
script(src="/socket.io/socket.io.js")
form(method='post', action="/")
input(type='text', id='user', autocomplete='off')
input(type='submit', onClick="myFunc()")
strong messages:
p(id="messages")
script.
var socket = io();
socket.on('message', function(msg) {
console.log('client: ' + msg);
});
function myFunc() {
var text = document.getElementById('user');
socket.emit('message', text.value);
text.value = '';
};
In your code example, io is a Socket.IO server instance attached to an instance of http.Server listening for incoming events.
The socket argument of the connection event listener callback function is an object that represents an incoming socket connection from a client.
Both of them can listen for events with the on method.
It might help you visually understand how the two are separate if you re-imagine your code sample like this:
var connectionEvent = function(socket) {
console.log('user connected');
socket.on('message', function(msg) {
console.log('message: ' + msg);
io.emit('message', msg);
});
};
io.on('connection', connectionEvent);

Load chat messages upon page load using websockets on node.js

Hi I'm developing a chat application using nodejs I'm new to node so I'm not very well familiar on its capabilities... I have made my application store its chat messages on mysql database only but I need to also display the past message and current one of a user here is the index.js
var mysql = require('mysql');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var validator;
var connection = mysql.createConnection({ // setup the connection
host : "localhost",
user : "root",
password: "",
})
function getStdout(command, args, fn) {
var childProcess = require('child_process').spawn(command, args);
var output = '';
childProcess.stdout.setEncoding('utf8');
childProcess.stdout.on('data', function(data) {
output += data;
});
childProcess.on('close', function() {
fn(output);
});
}
app.use('/assets', require('express').static(__dirname + '/assets'));
app.use('/temp', require('express').static(__dirname + '/temp'));
app.get('/', function(req, res){
//res.sendfile(__dirname + '/' +validator);
res.send(validator);
});
//you should have only one io.on('connection')
io.on('connection', function(socket){
socket.on('chat message', function(msg){
console.log('message: ' + msg);
var myMsg= msg; // obtain the incoming msg
var strQuery = "INSERT INTO chat_storage(chat) VALUES(?)"; // your SQL string
connection.query("use schat"); // select the db
connection.query( strQuery, myMsg, function(err, rows){
if(err) {
// handle errors
} else {
io.emit('chat message', msg);
// message received
}
});
});
});
getStdout('php', ['message.php'], function(output) {
validator = output;
//start your server after you get an output
http.listen(3000, function(){
console.log(validator);
});
});
now here is the page for loading the chat messages
<?php startblock('script') ?>
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(document).ready(function(){
$.ajax({
url: "localhost:3000/includes/message/store_chat.php",
type: "POST",
dataType: "html",
success: function (result) {
$("#messages").html(result);
}
});
});
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
</script>
<?php endblock(); ?>
My idea was to the chat messages once the page loads I was trying to achieve it using ajax as you can see on the script that I have provided.. but it was no good didnt work at all Please help me
Couple of suggestions:
1) Store all of your messages in-memory ( unless you see this growing to several MB of data ) so that you can catch up any new client quickly.
2) Use socket.io to send the chat messages that have been stored rather than an AJAX call.
I've also included SequelizeJS instead of raw MySQL - It has a much cleaner raw query model and allows you to transition into a DAO model of sorts if you want to.
app.js
// Highly suggest replacing raw mysql with SequelizeJS - http://sequelizejs.com/
var Sequelize = require('sequelize'),
app = require('express')(),
http = require('http').Server(app),
io = require('socket.io')(http);
var validator;
var messages = [];
var sequelize = new Sequelize('schat', 'root', '');
app.use('/assets', require('express').static(__dirname + '/assets'));
app.use('/temp', require('express').static(__dirname + '/temp'));
app.get('/', function(req, res){
res.send(validator);
});
io.on('connection', function(socket){
// Send all previously sent messages
for( i in messages ) {
socket.emit('chat message', messages[i]);
}
socket.on('chat message', function(msg){
console.log('message: ' + msg);
// Push the message into the in-memory array.
messages.push(msg);
// Storage the message for when the application is restarted.
sequelize.query('INSERT INTO chat_storage(chat) VALUES("'+msg'")').success(function() {
// Insert was successful.
}).error(function (err) {
// Error inserting message
});
// Send the message to everyone
socket.broadcast.emit('chat message', msg);
});
});
function getStdout(command, args, fn) {
var childProcess = require('child_process').spawn(command, args);
var output = '';
childProcess.stdout.setEncoding('utf8');
childProcess.stdout.on('data', function(data) {
output += data;
});
childProcess.on('close', function() {
fn(output);
});
}
// Load Messages
sequelize.query('SELECT chat FROM chat_storage').success(function (rows) {
for( i in rows ) {
messages.push(rows[i].chat);
}
getStdout('php', ['message.php'], function(output) {
validator = output;
http.listen(3000, function(){
// Start server.
});
});
}).error(function (err) {
// Error!
});
php include
<?php startblock('script') ?>
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#messages').append($('li').text($('#m').val()));
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
</script>
<?php endblock(); ?>

Why isn't the server sending or the client receiving data via socket.io in my express app?

My node app posts an object (consisting of data collected in a form on the client) to Salesforce via their API. On receiving a success or error message, I would like to send it to the client-side, then display it. Socket.io seemed like the tool for this in my simple node/express3 app, but beyond the simple demo I'm not able to get data to pass between my server and my client.
My relevant server side code:
var express = require('express');
var port = 5432;
var app = module.exports = express();
var server = require('http').createServer(app);
var nforce = require('nforce');
var org = nforce.createConnection({
clientId: 'MY_CLIENT_ID',
clientSecret: 'MY_CLIENT_SECRET',
redirectUri: 'http://localhost:5432/oauth/_callback'
});
var io = require('socket.io').listen(server);
// here I authenticate with Salesforce, this works fine
app.post('/salesforce', function(req, res){
var lead = nforce.createSObject('Lead');
// here I construct the lead object, which also works fine
org.insert(lead, oauth, function(err, res) {
if (err === null) {
console.log(res);
leadSuccessMessage(res);
}
else {
console.log(err);
var error = {
errorCode: err.errorCode,
statusCode: err.statusCode,
messageBody: err.messageBody
};
console.log(error);
leadErrorMessage(error);
}
});
}
function leadSuccessMessage(res) {
var resp = res;
console.log('called success message from server');
io.sockets.on('connection', function (socket) {
socket.emit('sfRes', resp);
socket.on('thanks', function (data) {
console.log(data);
});
});
}
function leadErrorMessage(error) {
var err = error;
console.log('called error message from server');
io.sockets.on('connection', function (socket) {
console.log("socket is: " + socket);
socket.emit('sfRes', err);
socket.on('thanks', function (data) {
console.log(data);
});
});
}
And my relevant client side scripts:
<script src="/socket.io/socket.io.js"></script>
<script>
current.page = document.URL;
console.log("current page is: " + current.page);
var socket = io.connect(current.page);
socket.on('sfRes', function (data) {
console.log("client received: " + data);
fst.showLeadStatus(data);
socket.emit('thanks', {message: "received server feedback"});
});
</script>
When I post the form containing valid data using a spicy little AJAX call:
postToSF: function(){
$('#submitLead').on('click', function(e){
e.preventDefault();
var formData = $('#lead_form').serialize();
$.ajax({
type: 'POST',
url: '/salesforce',
data: formData,
success: function(){
fst.log('success!');
},
error: function(xhr, ajaxOptions, thrownError){
console.error(xhr.status); // 0
console.error(thrownError);
}
});
});
}
All I get are tears, and these in the server-side console:
// the result of `console.log(res)`
{ id: '00Qa000001FZfhKEAT', success: true, errors: [] }
// and proof that `leadSuccessMessage()` got called
called success message from server
Instead of calling this function from a client-side object as it's supposed to:
showLeadStatus: function(response){
if (response.success) {
fst.log("showing lead status as: " + response);
$('#leadStatus').addClass('success').removeClass('error').fadeIn().delay(4000).fadeOut();
}
else {
fst.log("showing lead status as: " + response);
$('#leadStatus').text(response.messageBody).addClass('error').removeClass('success').fadeIn().delay('4000').fadeOut();
}
$('#startOver').click();
}
Which works fine if I call it in the console passing it the data the server is supposed to be socketing over:
// this works, gosh darn it
fst.showLeadStatus({ id: '00Qa000001FZfhKEAT', success: true, errors: [] });
The Salesforce post error case doesn't surface anything to the client either. And there are no errors in the client or server console to contend with.
I'm stumped. Please help!
I would do something like this -
var mysocket = null;
var io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
mysocket = socket;
socket.on('thanks', function (data) {
console.log(data);
});
});
app.post('/salesforce', function(req, res){
....
....
})
function leadSuccessMessage(res) {
var resp = res;
console.log('called success message from server');
if(mysocket)
mysocket.emit('sfRes', resp);
}
function leadErrorMessage(error) {
var err = error;
console.log('called error message from server');
if(mysocket)
mysocket.emit('sfRes', err);
}

Resources