What is the websockets server location for this code? - javascript

I have a socket.io client code that has been tested to work with the server.
<script>
// create a new websocket
var socket = io.connect('http://localhost:8000');
// on message received we print all the data inside the #container div
socket.on('notification', function (data) {
var usersList = "<dl>";
$.each(data.users,function(index,user){
usersList += "<dt>" + user.user_name + "</dt>\n" +
"<dd>" + user.user_description + "\n" +
"<figure> <img class='img-polaroid' width='50px' src='" + user.user_img + "' /></figure>"
"</dd>";
});
usersList += "</dl>";
$('#container').html(usersList);
$('time').html('Last Update:' + data.time);
});
I tried to use a simple Web Socket client tester software. The one I am using is the Chrome extension "Simple Web Socket Client".
I need to key in the URL for the Websockets server. I keyed in
ws://localhost:8000/notification
It did not work. I just got an "undefined" error. What URL should I key in for the Websockets server?
Here are the relevant server code.
// creating the server ( localhost:8000 )
app.listen(8000);
var updateSockets = function(data) {
// adding the time of the last update
data.time = new Date();
console.log('Pushing new data to the clients connected ( connections amount = %s ) - %s', connectionsArray.length , data.time);
// sending new data to all the sockets connected
connectionsArray.forEach(function(tmpSocket) {
tmpSocket.volatile.emit('notification', data);
});
};
EDIT:Both the server and client were developed using socket.io

Related

Send Video between servers using Node

i am working in a project using node. My goal is to get a video from one server to the other. I am using udp protocol, so, i just want to know, how i must work with the video and how to do that. I mean, must i convert the video to a string and sent it by the socket udp? I know how to send strings, but i don't know how to apply this using video. Cpuld you help me please?
This is the code i use for the listening server:
var PORT = 33333;
var HOST = '127.0.0.1';
var dgram = require('dgram');
var server = dgram.createSocket('udp4');
server.on('listening', function () {
var address = server.address();
console.log('UDP Server Running on ' + address.address + ":" + address.port);
});
server.on('message', function (message, remote) {
console.log(remote.address + ':' + remote.port +' - ' + message);
});
server.bind(PORT, HOST);
Regards

Socketio 1.0 get attributes from all clients

I am currently working on a simple socketio application in which i am sending some parameters to envents and i am storing them into each socket.
socket.on('add user', function (data) {
if (addedUser) return;
// we store the username in the socket session for this client.
socket.nickname = data.nickname;
socket.userId = data.userId;
...
Then i am getting all socketio clients using var io.engine.clients and i am trying to obtain that parameters in other event like this:
socket.on('new message', function (data) {
var clientsRoom = io.engine.clients;
for(var c in clientsRoom){
console.log(" Client: " + c.userId); //Error
console.log(" Client: " + c); //outputs the socket ID
console.log(" Client: " + c['userId']); //Error
}
...
but i am unable to get my userID previously stored for all sockets. ¿What am i doing wrong?
Thanks.
Instead of io.engine.clients, you should use io.sockets.sockets (they aren't the same, socket.io adds an extra layer on top of engine.io). Also make sure that you treat it as an object, not an array:
var clientsRoom = io.sockets.sockets;
for (var id in clientsRoom) {
var c = clientsRoom[id];
console.log(" Client: " + c.userId);
console.log(" Client: " + id);
}

Multiple Clients connected to the same Server using UDP in NodeJS

Is it possible to have multiple clients to the same UDP server ?
I'd like to broadcast the same data to all connected clients.
Here would be a starting sample, if it helps somehow ...
// Server
var news = [
"Borussia Dortmund wins German championship",
"Tornado warning for the Bay Area",
"More rain for the weekend"
];
var dgram = require('dgram');
var server = dgram.createSocket("udp4");
server.bind(function() {
server.setBroadcast(true)
server.setMulticastTTL(128);
setInterval(broadcastNew, 3000);
});
function broadcastNew() {
var message = new Buffer(news[Math.floor(Math.random() * news.length)]);
server.send(message, 0, message.length, 5007, "224.1.1.1");
console.log("Sent " + message + " to the wire...");
}
// Client 1
var PORT = 5007;
var dgram = require('dgram');
var client = dgram.createSocket('udp4');
client.on('listening', function() {
var address = client.address();
console.log('UDP Client listening on ' + address.address + ":" + address.port);
client.setBroadcast(true)
client.setMulticastTTL(128);
client.addMembership('224.1.1.1');
});
client.on('message', function(message, remote) {
console.log('A: Epic Command Received. Preparing Relay.');
console.log('B: From: ' + remote.address + ':' + remote.port + ' - ' + message);
});
client.bind(PORT);
// Client 2
// Here would go another client, it is possible ?
Yes, it is possible.
I won't go on a speech about how you should use TCP before UDP and only use UDP when absolutely necessary.
For your problem, the fact is that UDP doesn't have any "connection". You receive messages, you send messages, but there is no "connection".
So what you should do is:
When receiving a message from an incoming client, store the IP/Port used by the client
When wanting to send messages to clients, send to all the IP/Port combinations stored
Periodically remove old clients (for example who didn't send a message in the last 5 minutes)
You can detect when a message is received on a bound socket after the "message" event. Your code would look something like that (helped myself):
// Server
var news = [
"Borussia Dortmund wins German championship",
"Tornado warning for the Bay Area",
"More rain for the weekend"
];
var clients = {};
const dgram = require('dgram');
const server = dgram.createSocket('udp4');
server.on('error', (err) => {
console.log(`server error:\n${err.stack}`);
server.close();
});
server.on('message', (msg, rinfo) => {
console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
clients[JSON.stringify([rinfo.address, rinfo.port])] = true;
//use delete clients[client] to remove from the list of clients
});
function broadCastNew() {
var message = new Buffer(news[Math.floor(Math.random() * news.length)]);
for (var client in clients) {
client = JSON.parse(client);
var port = client[1];
var address = client[0];
server.send(message, 0, message.length, port, address);
}
console.log("Sent " + message + " to the wire...");
}
server.on('listening', () => {
var address = server.address();
console.log(`server listening ${address.address}:${address.port}`);
setInterval(broadcastNew, 3000);
});
server.bind(5007);
Now whenever your server gets an UDP message on port 5007, it will add the sender to the list of clients, and every 3 seconds it will send a message to all the clients stored. How to make the sender receive that piece of news is another story, but you can use a tool such as WireShark to confirm yourself that it was correctly sent back.
Here I didn't delete old clients but you probably should include a mechanism to store the last time they contacted you (instead of using = true you can for example store current time, then periodically remove old clients)
Broadcast and Multicast are probably different from what you imagine, broadcast is used for example to send a message to everyone on the local network.

How to bind socket to more than one port, NodeJS

I have set up a node application which receives packets from a Port at an IP address and serves the contents to a web-page. This IP address has traffic going through two ports, 9999 and 10000. My application has the following code:
var PORT_ONE = 9999;
var PORT_TWO = 10000;
var SENSOR = '239.0.0.1';
var client = require('dgram').createSocket('udp4');
var dns = require('dns');
/* Client starts listening on IP */
client.on('listening', function () {
console.log('UDP Client listening on ' + SENSOR + ":" + PORT_TWO);
client.setMulticastTTL(1);
client.addMembership(SENSOR);
});
/* Client receives a message */
client.on('message', function (message, remote) {
var tempMessage = message.toString(); //cast Buffer var to String
var delimiter = "\n";
var tempData = tempMessage.split(delimiter);
console.log('From: ' + remote.address + ':' + remote.port +' - \n' + message);
var data = {
ip: [SENSOR],
info: [tempData]
};
sendMessage(data);
});
client.bind(PORT_ONE);
client.bind(PORT_TWO); //error here
When I run my node application in the terminal, I receive the error
dgram.js:163
throw new Error('Socket is already bound');
Where dgram.js is part of the Nodejs libraries. The error comes when binding to PORT_TWO. Is there a way to bind the socket to more than one port?
I want to add my 2 cents here, what I normally do is create array of ports and Ips and put in for loop binding on them one by one
udpclients = [5550,5551];
udpsockets=[]
var dgram = require('dgram');
udpclients.forEach(function(port){
var udpServer = dgram.createSocket('udp4');
udpServer.bind(port,'127.0.0.1')
udpServer.on('listening', function() {
var address = udpServer.address()
console.log("listening"+address.address+" port::"+address.port)
});
udpServer.on('message', function(msg, rinfo) {
console.log("message received :: "+ msg +" address::"+rinfo.address+ "port = "+ rinfo.port )
});
});
Or you can bind multiple sockets, wrap them into streams and then combine streams to get feeling of one single socket.

Send Broadcast datagram

I need to send a broadcast datagram to all machine (servers) connected to my network.
I'm using NodeJS Multicast
Client
var dgram = require('dgram');
var message = new Buffer("Some bytes");
var client = dgram.createSocket("udp4");
client.send(message, 0, message.length, 41234, "localhost");
// If I'm in the same machine 'localhost' works
// I need to do something 192.168.0.255 or 255.255.255
client.close();
Servers
var dgram = require("dgram");
var server = dgram.createSocket("udp4");
server.on("message", function (msg, rinfo) {
console.log("server got: " + msg + " from " +
rinfo.address + ":" + rinfo.port);
});
server.on("listening", function () {
var address = server.address();
console.log("server listening " + address.address + ":" + address.port);
});
server.bind(41234);
Thanks.
I spent a lot of time trying to be able to do UDP broadcasting and multicasting between computers. Hopefully this makes it easier for others since this topic is quite difficult to find answers for on the web. These solutions work in Node versions 6.x-12.x:
UDP Broadcasting
Calculate the broadcast address
Broadcast address = (~subnet mask) | (host's IP address) - see Wikipedia. Use ipconfig(Windows) or ifconfig(Linux), or checkout the netmask module.
Server (remember to change BROADCAST_ADDR to the correct broadcast address)
var PORT = 6024;
var BROADCAST_ADDR = "58.65.67.255";
var dgram = require('dgram');
var server = dgram.createSocket("udp4");
server.bind(function() {
server.setBroadcast(true);
setInterval(broadcastNew, 3000);
});
function broadcastNew() {
var message = Buffer.from("Broadcast message!");
server.send(message, 0, message.length, PORT, BROADCAST_ADDR, function() {
console.log("Sent '" + message + "'");
});
}
Client
var PORT = 6024;
var dgram = require('dgram');
var client = dgram.createSocket('udp4');
client.on('listening', function () {
var address = client.address();
console.log('UDP Client listening on ' + address.address + ":" + address.port);
client.setBroadcast(true);
});
client.on('message', function (message, rinfo) {
console.log('Message from: ' + rinfo.address + ':' + rinfo.port +' - ' + message);
});
client.bind(PORT);
UDP Multicasting
Multicast addresses
Looking at the IPv4 Multicast Address Space Registry and more in-depth clarification in the RFC 2365 manual section 6, we find the appropriate local scope multicast addresses are 239.255.0.0/16 and 239.192.0.0/14 (that is, unless you obtain permission to use other ones).
The multicast code below works just fine on Linux (and many other platforms) with these addresses.
Most operating systems send and listen for multicasts via specific interfaces, and by default they will often choose the wrong interface if multiple interfaces are available, so you never receive multicasts on another machine (you only receive them on localhost). Read more in the Node.js docs. For the code to work reliably, change the code so you specify the host's IP address for the interface you wish to use, as follows:
Server - server.bind(SRC_PORT, HOST_IP_ADDRESS, function() ...
Client - client.addMembership(MULTICAST_ADDR, HOST_IP_ADDRESS);
Take a look at these supporting sources: NodeJS, Java, C#, and a helpful command to see which multicast addresses you are subscribed to - netsh interface ipv4 show joins.
Server
var SRC_PORT = 6025;
var PORT = 6024;
var MULTICAST_ADDR = '239.255.255.250';
var dgram = require('dgram');
var server = dgram.createSocket("udp4");
server.bind(SRC_PORT, function () { // Add the HOST_IP_ADDRESS for reliability
setInterval(multicastNew, 4000);
});
function multicastNew() {
var message = Buffer.from("Multicast message!");
server.send(message, 0, message.length, PORT, MULTICAST_ADDR, function () {
console.log("Sent '" + message + "'");
});
}
Client
var PORT = 6024;
var MULTICAST_ADDR = '239.255.255.250';
var dgram = require('dgram');
var client = dgram.createSocket('udp4');
client.on('listening', function () {
var address = client.address();
console.log('UDP Client listening on ' + address.address + ":" + address.port);
});
client.on('message', function (message, rinfo) {
console.log('Message from: ' + rinfo.address + ':' + rinfo.port + ' - ' + message);
});
client.bind(PORT, function () {
client.addMembership(MULTICAST_ADDR); // Add the HOST_IP_ADDRESS for reliability
});
UPDATE: There are additional options for server.send (named socket.send in the docs). You can use a string for the msg instead of a Buffer, and depending on your version, several parameters are optional. You can also check whether an error has occurred in the callback function.
UPDATE: Since Node.js v6, new Buffer(str) is deprecated in favor of Buffer.from(str). The code above has been updated to reflect this change. If you are using an earlier version of Node, use the former syntax.
I never used Node.js, but I do recall that with Berkely sockets (which seem to be the most widely used implementation of sockets) you need to enable the SO_BROADCAST socket option to be able to send datagrams to the broadcast address. Looking up the dgram documentation, there seems to be a function for it.
var client = dgram.createSocket("udp4");
client.setBroadcast(true);
client.send(message, 0, message.length, 41234, "192.168.0.255");
You might want to find out the broadcast address programmatically, but I can't help you with that.
I think since node 0.10.0 some things has changed this works for me now:
//var broadcastAddress = "127.255.255.255";
var broadcastAddress = "192.168.0.255";
var message = new Buffer("Some bytes");
var client = dgram.createSocket("udp4");
client.bind();
client.on("listening", function () {
client.setBroadcast(true);
client.send(message, 0, message.length, 6623, broadcastAddress, function(err, bytes) {
client.close();
});
});
Hope this helps somebody ;)
If you want a AUTOMATIC BROADCAST ADDRESS yo can do:
const broadcastAddress = require('broadcast-address');
const os = require("os")
var PORT = 1234;
var dgram = require('dgram');
var server = dgram.createSocket("udp4");
server.bind(function() {
server.setBroadcast(true);
setInterval(broadcastNew, 5000);
});
function broadcastNew() {
var message = Buffer.from("Broadcast message!");
Object.keys(os.networkInterfaces()).forEach(it=>{
console.log(broadcastAddress(it));
server.send(message, 0, message.length, PORT, broadcastAddress(it), function() {
console.log("Sent '" + message + "'");
});
})
}
This code will get a broadcast address for each interface on you server and send a message.
;) reguards
NOTE: dont forget install broadcast-address = "npm i broadcast-address"

Categories