Http server with socket-io on node.js doens't running - javascript

My http server on node.js using socket-io isn't running. I used npm install socket-io and running server.
This is the server's code.
var static = require('node-static');
var http = require('http');
// Create a node-static server instance
var file = new(static.Server)();
// We use the http moduleƕs createServer function and
// rely on our instance of node-static to serve the files
var app = http.createServer(function (req, res) {
file.serve(req, res);
}).listen(8181);
// Use socket.io JavaScript library for real-time web applications
var io = require('socket.io').listen(app);
// Let's start managing connections...
io.sockets.on('connection', function (socket){
// Handle 'message' messages
socket.on('message', function (message) {
log('S --> got message: ', message);
// channel-only broadcast...
socket.broadcast.emit('message', message);
});
// Handle 'create or join' messages
socket.on('create or join', function (room) {
/*var namespace = '/';
for (var numClients in io.nsps[namespace].adapter.rooms[room]) {
console.log(numClients);
}*/
//var numClients = io.sockets.clients(room).length;
var numClients = io.sockets.adapter.rooms[room]!=undefined ? Object.keys(io.sockets.adapter.rooms[room]).length:0;
log('SERVER: CLIENTS ' + room + ' has ' + numClients + ' client(s)');
log('S --> Room ' + room + ' has ' + numClients + ' client(s)');
log('S --> Request to create or join room', room);
// First client joining...
if (numClients == 0){
socket.join(room);
socket.emit('created', room);
} else if (numClients == 1) {
// Second client joining...
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room);
log('S: sent JOIN message');
} else { // max two clients
socket.emit('full', room);
}
});
function log(){
var array = [">>> "];
for (var i = 0; i < arguments.length; i++) {
array.push(arguments[i]);
}
socket.emit('log', array);
}
});
While this is client's code connecting to the socket:
var room = getParameterByName('room_name');
alert ("room_name: "+room);
// Connect to signalling server
var socket = io.connect();
// Send 'Create or join' message to singnalling server
if (room !== '') {
console.log('Create or join room', room);
socket.emit('create or join', room);
}
With netstat -a comand I saw what the server's port is active.. but it doesn't send messages.
I've another question: how can server sends messages not in broadcast, but to specified peers connected? I mean: instead of
socket.on('message', function (message) {
log('S --> got message: ', message);
// channel-only broadcast...
socket.broadcast.emit('message', message);
});
How could I do? Thanks!

I've another question: how can server sends messages not in broadcast,
but to specified peers connected?
The second part of your question is that you just do socket.emit() to send to a single socket like this to send back to the same socket that just sent you a message:
socket.on('message', function (message) {
log('S --> got message: ', message);
// channel-only broadcast...
socket.emit('message', "got your message");
});
Or, if you have a socket id value for some other connected client, you can fetch that socket on the server like this:
io.sockets.connected[id].emit(...)

Related

How to connect IBM Watson IOT using Paho MQTT javascript client?

I am trying to connect IBM Watson IoT platform using Paho MQTT Javascript client as mentioned in the below example code.
var client = new Messaging.Client("myOqgId.messaging.internetofthings.ibmcloud.com", 8883, "myclientid_" + parseInt(Math.random() * 100, 10));
//Gets called if the websocket/mqtt connection gets disconnected for any reason
client.onConnectionLost = function (responseObject) {
//Depending on your scenario you could implement a reconnect logic here
alert("connection lost: " + responseObject.errorMessage);
};
//Gets called whenever you receive a message for your subscriptions
client.onMessageArrived = function (message) {
//Do something with the push message you received
$('#messages').append('<span>Topic: ' + message.destinationName + ' | ' + message.payloadString + '</span><br/>');
};
//Connect Options
var options = {
userName: API-Key here,
password: Auth token here,
timeout: 3,
//Gets Called if the connection has sucessfully been established
onSuccess: function () {
alert("Connected");
},
//Gets Called if the connection could not be established
onFailure: function (message) {
alert("Connection failed: " + message.errorMessage);
}
};
//Creates a new Messaging.Message Object and sends it to the HiveMQ MQTT Broker
var publish = function (payload, topic, qos) {
//Send your message (also possible to serialize it as JSON or protobuf or just use a string, no limitations)
var message = new Messaging.Message(payload);
message.destinationName = topic;
message.qos = qos;
client.send(message);
}
But not able to connect.
I am getting this error:
WebSocket connection to 'ws://myOrgIdXYZ.messaging.internetofthings.ibmcloud.com:8883/mqtt' failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET
Please anybody out there who tried connecting IBM Watson IoT using Paho Mqtt client.
Thank you all for your responses. Based on all responses I have made changes in my code.
<script type="text/javascript">
var clientId = 'a:myOrgId:'+Math.random().toString(16).substr(2, 8);
var client = new Messaging.Client("myOqgId.messaging.internetofthings.ibmcloud.com", 1883, clientId);
//Gets called if the websocket/mqtt connection gets disconnected for any reason
client.onConnectionLost = function (responseObject) {
//Depending on your scenario you could implement a reconnect logic here
alert("connection lost: " + responseObject.errorMessage);
};
//Gets called whenever you receive a message for your subscriptions
client.onMessageArrived = function (message) {
//Do something with the push message you received
$('#messages').append('<span>Topic: ' + message.destinationName + ' | ' + message.payloadString + '</span><br/>');
};
//Connect Options
var options = {
userName: API-Key here,
password: Auth token here,
timeout: 3,
//Gets Called if the connection has sucessfully been established
onSuccess: function () {
alert("Connected");
},
//Gets Called if the connection could not be established
onFailure: function (message) {
alert("Connection failed: " + message.errorMessage);
}
};
//Creates a new Messaging.Message Object and sends it to the HiveMQ MQTT Broker
var publish = function (payload, topic, qos) {
//Send your message (also possible to serialize it as JSON or protobuf or just use a string, no limitations)
var message = new Messaging.Message(payload);
message.destinationName = topic;
message.qos = qos;
client.send(message);
}
client.connect(options);
</script>
You can see that I have made changes in ClientId. IBM Watson Iot will accept only the client ids in the below format if you are not using Watson IoT libraries.
var clientId = 'a:OrgId:'+RandomString;
If you are using IBM Watson IoT libraries Client Id can be anything. Even I implemented in node.js

Node.js Processes Don't Detect Port is Already Being Used

I am trying to have two different Node processes (using Cluster) try to become servers to a Port. However, whenever the second process gets to the port, it doesn't detect that the port is being used.
I suspect the reason why they are not detecting if the port is open or not is due to the nature of callbacks (I'm detecting if the port is used or not using the portInUse function, so it is fetched asynchronously, and might cause some type of conflict later on).
Here is the code:
var cluster = require('cluster');
var net = require('net');
var PORT = 1337;
var list = {};
var portIsBeingUsed = false;
// Variable that detects if the port is in use.
var portInUse = function(port, callback) {
var server = net.createServer(function(socket) {
socket.write('Echo server\r\n');
socket.pipe(socket);
});
server.listen(port, 'localhost');
server.on('error', function (e) {
callback(true);
});
server.on('listening', function (e) {
server.close();
callback(false);
});
};
if (cluster.isMaster) {
for (var i = 0; i < 2; i++) {
cluster.fork();
}
Object.keys(cluster.workers).forEach(function(id) {
console.log("I am running with ID : "+ cluster.workers[id].process.pid);
list[cluster.workers[id].process.pid] = 0;
});
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
} else { // Rest of the logic with all Processes goes here.
// Get the Process ID of the current process in execution.
var pid = cluster.worker.process.pid;
console.log("This is process " + pid + " working now.\n");
// Verify if Port is being used.
portInUse(PORT, function(returnValue) {
if(returnValue) { // Become a Client to the Server
console.log("port " + PORT + " is being used.\n\n");
becomeClient(pid);
} else { // Become a Server
console.log("port" + PORT + " is not being used.\n\n");
becomeServer(pid);
}
});
}
function becomeServer(pid) {
var server = list[pid];
server = net.createServer(function (socket) {
socket.write('Hello Server 1\r\n');
socket.end("hello");
console.log("Someone connected to Server 1. \n");
socket.pipe(socket);
});
server.listen(PORT, function(){
console.log("Process " + pid + " has become the Server on Port " + PORT);
});
server.on("error", function() {
console.log("there was an error on Process " + pid);
console.log("this error was becoming a Server.");
});
}
function becomeClient(pid) {
var client = list[pid];
client = net.connect({port: PORT}, function() {
list[pid].write("I am connected to the port and my pid is " + pid);
});
client.on('data', function(data) {
console.log(data.toString());
list[pid].end();
});
client.on('end', function() {
console.log('disconnected from server');
});
}
And here is the output:
So the first process (In this case Process 9120) becomes the server on port 1337, but then the second process doesn't detect that the port is being used and somehow becomes the server as well (I would expect an EADDRINUSE here, not sure why it isn't showing any errors).
Any help or clarification as to why this isn't working would be greatly appreciated.
Thanks,
This is expected behavior and it is how the cluster module works (by default). It's what allows incoming requests to the same port to be easily distributed among the available workers.
A large part of the point of cluster involves port sharing, so that you can have multiple workers take turns serving requests. The worker processes just request a port from the master, which actually opens the port, and then the master hands requests back to any workers that have requested that port.

How do I close a sockjs connection on the server side?

So, every time I refresh the page, it seems like sockjs is creating a new connection.
I am saving every message to my mongodb on every channel.onmessage, so if I refresh my page 7 times and send a message, I would save 7 messages of the same content into my mongodb.
This is very problematic because when I retrieve those messages when I go into the chat room, to see the log, I would see bunch of duplicate messages.
I want to keep track of all connections that are 'active', and if a user tries to make another connections, I want to be able to force close on the old one from the server side, so there is only 1 connection listening to each message at a time
How do I do this ?
var connections = {};
//creating the sockjs server
var chat = sockjs.createServer();
//installing handlers for sockjs server instance, with the same url as client
chat.installHandlers(server, {prefix:'/chat/private'});
var multiplexer = new multiplexServer.MultiplexServer(chat);
var configChannel = function (channelId, userId, userName){
var channel = multiplexer.registerChannel(channelId);
channel.on('connection', function (conn) {
// console.log('connection');
console.log(connections);
connections[channelId] = connections[channelId] || {};
if (connections[channelId][userId]) {
//want to close the extra connection
} else {
connections[channelId][userId] = conn;
}
// }
// if (channels[channelId][userId]) {
// conn = channels[channelId][userId];
// } else {
// channels[channelId][userId] = conn;
// }
// console.log('accessing channel! ', channels[channelId]);
conn.on('new user', function (data, message) {
console.log('new user! ', data, message);
});
// var number = connections.length;
conn.on('data', function(message) {
var messageObj = JSON.parse(message);
handler.saveMessage(messageObj.channelId, messageObj.user, messageObj.message);
console.log('received the message, ', messageObj.message);
conn.write(JSON.stringify({channelId: messageObj.channelId, user: messageObj.user, message: messageObj.message }));
});
conn.on('close', function() {
conn.write(userName + ' has disconnected');
});
});
return channel;
};
Simply use .close:
if (connections[channelId][userId]) {
// want to close the extra connection
connections[channelId][userId].close();
} else {
connections[channelId][userId] = conn;
}

webrtc video chat server hosted on heroku

I am trying to build a simple video chat service using webrtc. I am referring to the tutorial given in html5rocks article introducing webrtc basics..[http://www.html5rocks.com/en/tutorials/webrtc/basics/][1]
The server.js is working fine with node-static on the localhost with perfect video streaming and chat service.The problem is when i am trying to host it on heroku ..the video stream doesnt work or should i say none of the functionality of server.js work..Browser window just shows a text box which is the basic layout of my index.html file..So there is definitely some problem in my code .something is missing in server.js file which is required for hosting on heroku..Here is the code for Server.js..Please help me to resolve the issue..Tell me the correct way of hosting it as i know i am missing something here..
var static = require('node-static');
/*var http = require('http');
var file = new(static.Server)();
var app = http.createServer(function (req, res) {
file.serve(req, res);
}).listen(2013);
*/
var express = require('express');
var app = express();
console.log(express.static(__dirname + '/js'));
app.use(express.static(__dirname + '/js'));
app.all('*', function(req, res){
res.sendfile("index.html");
});
app.listen(9000);
var io = require('socket.io').listen(app);
io.sockets.on('connection', function (socket){
function log(){
var array = [">>> "];
for (var i = 0; i < arguments.length; i++) {
array.push(arguments[i]);
}
socket.emit('log', array);
}
socket.on('message', function (message) {
log('Got message: ', message);
socket.broadcast.emit('message', message); // should be room only
});
socket.on('create or join', function (room) {
var numClients = io.sockets.clients(room).length;
log('Room ' + room + ' has ' + numClients + ' client(s)');
log('Request to create or join room', room);
if (numClients == 0){
socket.join(room);
socket.emit('created', room);
} else if (numClients == 1) {
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room);
} else { // max two clients
socket.emit('full', room);
}
socket.emit('emit(): client ' + socket.id + ' joined room ' + room);
socket.broadcast.emit('broadcast(): client ' + socket.id + ' joined room ' + room);
});
});

WebSocket on Node.js and share a message between all the connected clients

I've got a Node.js server with websocket module, installed through the following command:
npm install websocket
Starting from this guide, I decided to extend it sharing the sent messages between all the clients.
Here is my (simplified) server code:
#!/usr/bin/env node
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {
console.log((new Date()) + ' Received request for ' + request.url);
response.writeHead(404);
response.end();
});
server.listen(8080, function() {
console.log((new Date()) + ' Server is listening on port 8080');
});
wsServer = new WebSocketServer({
httpServer: server,
autoAcceptConnections: false
});
var connectedClientsCount = 0; // ADDED
var connectedClients = []; // ADDED
wsServer.on('request', function(request) {
var connection = request.accept('echo-protocol', request.origin);
connectedClientsCount++;
connectedClients.push(connection);
console.log((new Date()) + ' Connection accepted.');
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
for(c in connectedClients) // ADDED
c.sendUTF(message.utf8Data); // ADDED
}
else if (message.type === 'binary') {
console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
connection.sendBytes(message.binaryData);
}
});
connection.on('close', function(reasonCode, description) {
// here I should delete the client...
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
In this case I can get the connectedClientsCount value, but I can't manage the connectedClients list.
I also tried with ((eval)c).sendUTF(message.utf8Data); as for statement but it doesn't work.
I advise you to use Socket.IO: the cross-browser WebSocket for realtime apps. The module is very simple to install and configure
For example:
Server
...
io.sockets.on('connection', function (socket) {
//Sends the message or event to every connected user in the current namespace, except to your self.
socket.broadcast.emit('Hi, a new user connected');
//Sends the message or event to every connected user in the current namespace
io.sockets.emit('Hi all');
//Sends the message to one user
socket.emit('news', {data:'data'});
});
});
...
more
Client:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
//receive message
socket.on('news', function (data) {
console.log(data);
//send message
socket.emit('my other event', { my: 'data' });
});
</script>
more about exposed events
Try replacing for ... in by for ... of
for(c of connectedClients) // ADDED
c.sendUTF(message.utf8Data); // ADDED

Categories

Resources