guys, I have this doubt with websockets in javascript, I want to return the ip's connected to the server and i don't have idea to do it, I only want the ip's, I just want the ones that are connected at the moment.
Here is my server:
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('Server is listening on port 8080');
});
wsServer = new WebSocketServer({
httpServer: server,
autoAcceptConnections: false
});
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' request.origin + ' rejected.');
return;
}
var connection = request.accept('echo-protocol', request.origin);
console.log((new Date()) + ' Connection accepted.');
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
var ipAddress = connection.remoteAddress;
console.log(ipAddress);
connection.sendUTF("pablo puta");
}
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) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
Please, if you can help me, I would be very grateful.
I believe you can keep an object of ips:
var ips={};
connection.on('close', function(reasonCode, description) {
delete ips[connection.remoteAddress];
});
connection.on('open', function(reasonCode, description) {
ips[connection.remoteAddress]=true;
});
And then somehow response with:
Object.keys(ips);
to yourself...
(I believe it must be this instead of connection inside the handlers, but im not an expert in that...)
Related
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(...)
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.
I have a websocket client-server application. Here's client's simplified code:
const HOST = "wss://localhost:8000";
const SUB_PROTOCOL= "sub-protocol";
var websocket = new WebSocket(HOST, SUB_PROTOCOL);
websocket.onopen = function(evt) { ... };
websocket.onclose = function(evt) { ... };
websocket.onerror = function(evt) { ... };
websocket.onmessage = function(evt) { ... };
And here's server:
const PORT = 8000;
const SUBPROTOCOL = 'sub-protocol';
var WebSocketServer = require('websocket').server;
var https = require('https');
var fs = require('fs');
// Private key and certification (self-signed for now)
var options = {
key: fs.readFileSync('cert/server.key'),
cert: fs.readFileSync('cert/server.crt')
};
var server = https.createServer(options, function(request, response) {
console.log((new Date()) + ' Received HTTP(S) request for ' + request.url);
response.writeHead(404);
response.end();
});
// bind server object to listen to PORT number
server.listen(PORT, function() {
console.log((new Date()) + ' Server is listening on port ' + PORT);
});
wsServer = new WebSocketServer({
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
});
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
// If autoAcceptConnections is set to false, a request event will be emitted
// by the server whenever a new WebSocket request is made
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
// accepts connection and return socket for this connection
var connection = request.accept(SUB_PROTOCOL, request.origin);
console.log((new Date()) + ' Connection accepted.');
// when message is received
connection.on('message', function(message) {
// echo
connection.send(connection, message.utf8Data);
});
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
Both client and server works as expected even with some HTTPS pages (tested on Twitter, mail.ru,). But for some reason doesn't for example with Facebook or GitHub.
In JavaScript console I get this:
Exception { message: "", result: 2153644038, name: "", filename: "", lineNumber: 0, columnNumber: 0, inner: null, data: null }
Then huge stack trace follows: pasted it here
and at the end:
Content Security Policy: The page's settings blocked the loading of a resource at wss://localhost:8000/ ("connect-src https://github.com:443 https://ghconduit.com:25035 https://live.github.com:443 https://uploads.github.com:443 https://s3.amazonaws.com:443").
I don't see how does these page differ from pages, which works. I'd also like to point out, that these pages works in Chrome.
(tested in Firefox 31)
The pages where the WebSocket connection fails have a Content-Security-Policy header with the connect-src directive set to only allow connections to a set of whitelisted domains. This means that all connections from that page to any non-whitelisted domain will fail.
Its not clear how you're running this code. It seems possible that Chrome allows extensions to bypass that header restriction while Firefox does not, or something to that effect.
I have a node js server, and a html/javascript client.
I simply want to allow the client to send a json-string to the node.js server, the server process's that string and returns a result string back to the client.
I started by setting up the html-client to call like so :
var msg =
{
type: "message",
text: "Hello"
};
function CallWebSocket()
{
var socket = new WebSocket("ws://127.0.0.1:8080","test");
socket.onopen = function (event)
{
alert(JSON.stringify(msg));
socket.send(JSON.stringify(msg));
};
socket.onmessage = function(event)
{
alert(event.data);
}
}
and node.js :
var net = require('net');
var server = net.createServer(function(socket)
{
// do what you need
socket.setEncoding("utf8");
socket.on('data', function(data)
{
var jsonData = JSON.parse(data);
socket.write(jsonData.text);
socket.end();
process.exit(0);
});
});
server.listen(8080);
but on the server I get this error :
undefined:1
``GET / HTTP/1.1
^
SyntaxError: Unexpected token G
at Object.parse (native)
at Socket.<anonymous> (/home/jay/projects/nodejs/test/json-server.js:8:23)
at Socket.EventEmitter.emit (events.js:95:17)
at Socket.<anonymous> (_stream_readable.js:746:14)
at Socket.EventEmitter.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:408:10)
at emitReadable (_stream_readable.js:404:5)
at readableAddChunk (_stream_readable.js:165:9)
at Socket.Readable.push (_stream_readable.js:127:10)
at TCP.onread (net.js:526:21)
Any help is much appreciated.
UPDATE
The updated server code :
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,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
});
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
var connection = request.accept('echo-protocol', request.origin);
console.log((new Date()) + ' Connection accepted.');
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
connection.sendUTF(message.utf8Data);
}
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) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
This solved my problem and I am now getting the message back.
A websocket is not a plain TCP socket. That is basically the core of your problem.
The websocket protocol looks like a modified HTTP protocol that allows two way communication using a single (TCP) socket. Read the RFC for more info on how the websocket protocol actually works: https://www.rfc-editor.org/rfc/rfc6455#section-1.2
You have two options if you want to use websockets with node servers:
Read the RFC and write a function to handle the websocket protocol so you can pass that function to socket.on.
Use a websocket server module that someone else have written. Go to npm and search for "websocket server" or google "websocket server npm". There are lots of modules out there. Pick one you like best.
There is a third alternative. Use socket.io. Socket.io is a library that communicates between client and server using websocket if possible (preferred) but is able to degrade to other transports such as Flash and ajax on older browsers.
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