I've wrote a simple app and tested in Chrome. All works fine!
Now I'm testing with qupzilla, but when I trigger the .emit function, nothing happens!
From chrome i wrote a thing, the object is updated and sent to server, server does a broadcast. All fine (qupzilla receives the update too).
But, if I write something on qupzilla, this update isn't sent to server (No logs in node)
Here's some code.
Server side:
var io = require('socket.io').listen(8080);
io.set("log level", 1);
var dataStored = [];
io.sockets.on('connection', function (socket) {
socket.emit('event', dataStored);
socket.on('update', function (data) {
console.log(data);
dataStored = data;
socket.broadcast.emit("event", data);
});
});
And client side:
$scope.things = [];
$scope.pushingObj = "";
// socket
var socket = io.connect("http://localhost:8080", {
'connect timeout': 500,
reconnect: true,
'reconnection delay': 500,
'reopen delay': 500,
'max reconnection attempts': 10000
});
socket.on("event", function(data) {
$scope.things = data;
$scope.$apply();
});
//
$scope.pushObj = function() {
//console.log($scope.pushingObj);
$scope.things.push($scope.pushingObj);
socket.emit("update", $scope.things);
$scope.pushingObj = "";
}
Related
I'm playing around with Node, Socket.IO and BDD by creating a chat application. During one of the tests, I get a timeout error stating:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
The affected test is
it('#must be able to receive a message', function(done)
{
chatterServer.on('chatterMessage', function(data)
{
console.log('Incoming message!');
expect(data).to.have.property('message');
expect(data.message).to.be('Hello, world!');
done();
});
console.log('Sending message!');
chatterClient.send('chatterMessage', { message: 'Hello, world!' });
console.log('Sent!');
});
I found that the cause of this issue is that the chatterMessage event is not being caught by the server. Whilst I did specify it.
The console's output is:
Sending message!
Sent!
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
I'm probably doing something wrong. I'm not too familiar with Node and Socket.IO, so I'm sorry if this question is very obvious.
I looked around Google with the search terms 'socket.io server not receiving from client', but from what I found, nothing helped me to solve my issue so far.
I did however try the solution in this question, but that didn't fix it for me.
I'm using Mocha and expect.js
The complete test is:
var util = require('util');
var Chatter = require('../src/index');
var ChatterServer = Chatter.Server;
var ChatterClient = Chatter.Client;
var express = require('express');
var expect = require('expect.js');
var socketIO = require('socket.io');
var socketIOClient = require('socket.io-client');
var host = 'http://localhost';
var port = 8080;
describe('Chatter', function()
{
'use strict';
var chatterServer;
var chatterClient;
var server;
before(function()
{
var app = express();
server = app.listen(port);
});
beforeEach(function()
{
chatterServer = new ChatterServer(socketIO(server));
chatterClient = new ChatterClient(socketIOClient, util.format('%s:%s', host, port.toString()));
});
...
it('#must be able to receive a message', function(done)
{
chatterServer.on('chatterMessage', function(data)
{
console.log('Incoming message!');
expect(data).to.have.property('message');
expect(data.message).to.be('Hello, world!');
done();
});
console.log('Sending message!');
chatterClient.send('chatterMessage', { message: 'Hello, world!' });
console.log('Sent!');
});
});
My Client (ChatterClient) is:
(function()
{
'use strict';
function Client(socketIO, url)
{
this.socketIO = socketIO(url);
}
Client.prototype.send = function(event, data)
{
this.socketIO.emit(event, data);
};
Client.prototype.on = function(event, callback)
{
this.socketIO.on(event, callback);
};
if (module !== undefined && module.hasOwnProperty('exports')) {
module.exports = Client;
} else {
window.Chatter = {
Client: Client,
};
}
}());
The Server (ChatterServer) is:
(function()
{
'use strict';
function Server(socketIO)
{
this.socketIO = socketIO;
this.connectedUsers = {};
this.on('connection', (function(user)
{
var userID = user.client.id;
this.connectedUsers[userID] = user;
user.emit('chatterConnectionAcknowledged', { id: userID });
}).bind(this));
}
Server.prototype.on = function(event, handler)
{
this.socketIO.on(event, handler);
};
module.exports = Server;
}());
You need to change your code in two sides.
First side, you will need to listen incoming socket connections on the socketIO object. (see the emphasized code below)
//.. some code
function Server(socketIO)
{
this.socketIO = socketIO;
this.connectedUsers = {};
this.socketIO.on('connection', (function(user)
{
var userID = user.client.id;
this.connectedUsers[userID] = user;
user.emit('chatterConnectionAcknowledged', { id: userID });
}).bind(this));
}
//.. some code
Second side, when you are adding new events to listen on the server, you need to bind those events to the sockets since they are ones that are going to listen when events are emitted from the socket clients.
Server.prototype.on = function (event, handler) {
Object.keys(this.connectedUsers).map(function (key) {
this.connectedUsers[key].on(event, handler);
}.bind(this));
};
I am working on socket.io and i am new to this. I am trying to disconnect after n number of attempts to reconnect.
Server Side Code:
var io = require('socket.io').listen(4000);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Client side code is:
<script src="http://localhost:4000/socket.io/socket.io.js"></script>
<script>
//var max_reconnects, socket;
var max_reconnects = 5;
var socket = io.connect('http://localhost:4000',
{'reconnection delay': 100,
'max reconnection attempts': max_reconnects,
'reconnection limit' : 10});
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
socket.on("reconnecting", function(delay, attempt) {
console.log("attempting reconnect - " + attempt + "-->" + delay);
if (delay === max_reconnects) {
//return console.log("all reconnect attempts failed");
//socket.disconnect();
//socket.server.close();
socket.emit('forceDisconnect');
console.log("Limited end");
}
});
Please guide me how to terminate the reconnecting activity after number of attempts. the given code is not working properly. and reconnecting call back attempts is also undefined. Please guide me
Are you using socket.io >= 1.0 but using an example from before (there were some changes)?
Check here for the correct parameters: https://github.com/Automattic/socket.io-client#managerurlstring-optsobject
var socket = io.connect('http://localhost:4000',
{'reconnectionDelay': 100,
'reconnectionAttempts': max_reconnects});
I am very new to NodeJS and Websockets, but i am trying to play with it.
What i do is read incoming datas from Serial port, then send these datas to a web page using websocket.
From here everything works fine.
I use node-static to serve my web page
I use ws for websocket
The problem is when a client close his browser, then my NodeJS websocket server crashes with the following error :
root#WS-SERVER-2:~/app# node socketserver.js
open serial communication
Client disconnected.
/root/node-v0.10.29/lib/node_modules/ws/lib/WebSocket.js:187
else throw new Error('not opened');
^
Error: not opened
at WebSocket.send (/root/node-v0.10.29/lib/node_modules/ws/lib/WebSocket.js:187:16)
at sendAll (/root/app/socketserver.js:30:16)
at SerialPort.<anonymous> (/root/app/socketserver.js:58:8)
at SerialPort.emit (events.js:95:17)
at Object.module.exports.raw [as parser] (/root/node-v0.10.29/bin/node_modules/serialport/parsers.js:8:13)
at Object.SerialPort.options.dataCallback (/root/node-v0.10.29/bin/node_modules/serialport/serialport.js:143:15)
at SerialPortFactory.SerialPort._emitData (/root/node-v0.10.29/bin/node_modules/serialport/serialport.js:312:20)
at afterRead (/root/node-v0.10.29/bin/node_modules/serialport/serialport.js:290:18)
at /root/node-v0.10.29/bin/node_modules/serialport/serialport.js:304:9
at Object.wrapper [as oncomplete] (fs.js:459:17)
Here is my websocket/serialport code :
var WebSocketServer = require('../node-v0.10.29/lib/node_modules/ws').Server;
var SerialPort = require('../node-v0.10.29/bin/node_modules/serialport').SerialPort;
var serialPort;
var portName = '/dev/ttyACM0';
var sendData = "";
var wss = new WebSocketServer({port: 8080});
var CLIENTS=[];
wss.on('connection', function(ws) {
CLIENTS.push(ws);
ws.on('message', function(message) {
console.log('received: %s', message);
sendAll(message);
});
ws.on('close', function() {
console.log('Client disconnected.');
});
ws.on('error', function() {
console.log('ERROR');
});
ws.send("");
});
function sendAll(message)
{
for(var i=0;i<CLIENTS.length;i++)
{
CLIENTS[i].send(message);
}
}
serialListener();
function serialListener(debug)
{
var receivedData = "";
serialPort = new SerialPort(portName, {
baudrate: 9600,
dataBits: 8,
parity: 'none',
stopBits: 1,
flowControl: false
});
serialPort.on("open", function () {
console.log('open serial communication');
// Listens to incoming data
serialPort.on('data', function(data) {
receivedData += data.toString();
if (receivedData .indexOf('E') >= 0 && receivedData .indexOf('B') >= 0) {
sendData = receivedData .substring(receivedData .indexOf('B') + 1, receivedData .indexOf('E'));
receivedData = '';
}
// send the incoming data to browser with websockets.
sendAll(sendData);
});
});
}
Can someone help me to figure out what's wrong here ?
I think, you should remove the socket from your CLIENTS array on both close and error event. Otherwise it tries to send a message to a socket that is closed.
I was having this same issue. Turned out I was attempting to send events to sockets that were in the "closing" state. Checking that each socket was specifically open before broadcasting a message fixed it for me:
function sendAll(data){
for(var i = 0; i < clients.length; i++){
if(this.clients[i].readyState != this.clients[0].OPEN){
console.error('Client state is ' + this.clients[i].readyState);
}
else{
this.clients[i].send(data);
}
}
}
Try this while sending data to client:
- socket is my current web socket object.It overwrites the default >WebSocket.js class condition that throws "not-opened error".
if (socket.readyState != socket.OPEN) {
console.error('Client state is ' + socket.readyState);
//or any message you want
} else {
socket.send(JSON.stringify(object)); //send data to client
}
I have WebSocketServer listening to connecting clients. Unfortunately I can't find a way to check which client has closed a connection.
In
ws.on('close',function(){ });
how can I check which user ws belongs to?
var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 8080});
var playersConnected=[];
var playersConnectedByID=[];
var playersConnectedBySock=[];
wss.on('connection', function(ws) {
console.log("somebody connected");
playerID=Math.floor(Math.random() * (100000000 - 0+1) + 0);
playerID=playerID.toString();
ws.send("newID="+playerID);
//inserting new player into the right place
l=playersConnected.length; console.log("Current array length is "+l);
playersConnected[l]=([playerID,ws,"free"]);
l=playersConnected.length;
for(i=0;i<l;i++) console.log(i+" "+playersConnected[i][0]);
console.log("=================================================");
ws.on('close',function(){console.log("closing ");});
ws.on('message', function(message) {
console.log('%s send received mess %s',playerID,message);
}
);
});
process.on('uncaughtException', function (err) {
console.log("bad connect");
console.log(err);
});
Every function forms a closure for local variables, so you could just use an object which contains all necessary informations:
wss.on('connection', function(ws) {
var playerID = Math.floor(Math.random() * (100000000 - 0+1) + 0);
playerID = playerID.toString();
var connection = {
socket: ws,
playerID: playerID
};
console.log("connected",connection);
// add your other code here
ws.on('close',function(){
console.log("closing ", connection);
// you will probably change this to remove_from_userlist() or similar
});
});
With node.js, I'm trying to send the current server_time to all clients in every second.
Therefore, I wanted to use setInterval() to emit an event to all clients and sending the time, but it doesn't work. Did I define the setInterval function at the right place or did missed something else?
var http = require("http");
var socketIO = require('socket.io');
var connect = require('connect');
//keep track of every connected client
var clients = {};
//create Server
var httpServer = connect.createServer(
connect.static(__dirname)
).listen(8888);
//socket
var io = socketIO.listen(httpServer);
io.sockets.on('connection', function (socket) {
//add current client id to array
clients[socket.id] = socket;
socket.on('close', function() {
delete clients[socket.fd]; // remove the client.
});
//send news on connection to client
socket.emit('news', { hello: 'world' });
//this one works fine!
//send server time on connection to client
socket.emit("server_time", { time: new Date().toString() });
});
//this doesn't work!
// Write the time to all clients every second.
setInterval(function() {
var i, sock;
for (i in clients) {
sock = clients[i];
if (sock.writable) { // in case it closed while we are iterating.
sock.emit("server_time", {
console.log("server_time sended");
time: new Date().toString()
});
}
}
}, 1000); //every second
May I suggest a workaround/improvement that should fix the problem. Add the clients to a chat room. Somewhere in:
io.sockets.on('connection', function (socket) {
add a
socket.join('timer');
Then the setIntervall would be
setInterval(function() {
io.sockets.in('timer').emit("server_time", { time: new Date().toString() })
}, 1000);
Hope this works for you!
The problem is the following function:
if (sock.writable) { // in case it closed while we are iterating.
sock.emit("server_time", {
// console.log("server_time sended"); // get rid of this line -> invalid code
time: new Date().toString()
});
}
sock.writable is undefined and therefore the emit event is never sent. Set the property to true on connection and to false on close.