I have two applications A and B in Node Js and application B wants to communicate with application A.
Now Application A selects its port dynamically during run time. So how Application B can discover on which Port application A is running?
You can handle an event in app A and app B for ECONNREFUSED before starting your server in express which will take care of the port in used.if you see this error then just change the port number dynamically which will be true for both apps.
I did some more research and came up with solution which is "dns-discovery" and "openport"
First Check which port is open in your system using "openport" and then use "dns-discoverry".
Application A
var op = require('openport');
op.find(
{
startingPort: 8050,
endingPort: 8999
},
function (err, port) {
if (err) { console.log(err); return; }
console.log('opened port is:::::::::' + port);
ServerStart(port);
}
);
function ServerStart(port) {
var discovery = require('dns-discovery');
var disc = discovery();
disc.announce('connect-apps', port, function () {
console.log("announcement start")
});
var io = require('socket.io')(port);
io.on('connection', function (socket) {
socket.on('message', function (msg) {
console.log("Response From Client::::::::::::" + msg);
socket.send("Congratulations from Server");
});
socket.on('disconnect', function (msg) {
console.log("We are disconnected");
});
})
}
Application B
var discovery = require('dns-discovery')
var disc = discovery()
disc.lookup('connect-apps', function () {
console.log('Server Lookup Started:::::::::::::::::::')
})
disc.on('peer', function (name, peer) {
console.log("Server found:::::::::" + peer.host + ':::' + peer.port);
var ws = 'ws://' + peer.host + ':' + peer.port;
var socket = require('socket.io-client')(ws, { forceNew: true });
socket.io.opts.transports = ['polling', 'websocket'];
socket.on('connect', function () {
console.log('connected');
socket.send('Hello from Client 1::::::::Vishal Shori Machine');
});
socket.on('message', function (msg) {
console.log("response again::::::::::::" + msg);
});
disc.destroy();
})
For Reference :
https://www.npmjs.com/package/openport
https://github.com/mafintosh/dns-discovery
Related
I my app I use socket.io. Inside the client code I use
let socket;
const connect = () => {
let error = null;
socket = io({autoConnect: false});
socket.on('connect', () => {
console.log('Connected');
});
socket.on('disconnect', (reason) => {
console.log(`Disconnected: ${error || reason}`);
error = null;
});
socket.on('message', (message) => {
$("#messages").append(message + '<br/>');
let last = document.querySelector('#messages').lastElementChild;
last.scrollIntoView();
});
socket.open();
}
But it looks like that `enter code here
socket = io({autoConnect: false});
So not work well. Every time I open the side from node server, node reports a connection. Is there a problem in my syntax? I assume that the auto connect will avoid this case so the connection is only done when call connect().
I think
socket = io({autoConnect: false, reconnection: false});
is the solution
Hey uh I am having an issue and I think this is probably related to net.createserver.
The issue is that whenever the first client joins after that another second client joins, the first client can control the second client and then the first client disconnects because the socket(end) event gets triggered. Is it related to sockets or something or the server can't handle two connections? Please help
The code:
handleGame: function() {
console.log(log.success('The source is starting!'));
var server = net.createServer(function(socket) {
console.log('A client has connected' + "\r\n");
socket.setEncoding('utf8')
global.clientObjz = new client(socket);
game.addClient(clientObjz);
socket.on('data', function(data) {
data = data.toString().split('\0')[0];
console.log('Incoming data: ' + data + "\r\n")
if (data == "<msg t='sys'><body action='verChk' r='0'><ver v='153' /></body></msg>" | data == "<msg t='sys'><body action='rndK' r='-1'></body></msg>" | data.startsWith("<msg t='sys'><body action='login' r='0'>")) {
parseXml(data, function(err, result) {
var type = result.msg['$'].t,
action = result.msg.body[0]['$'].action;
var method = Game.xmlHandlers[type][action];
if (typeof Game[method] == 'function') {
Game[method](data, client);
}
});
}
var dataType = data.charAt(0);
if (dataType == '%') {
game.handleraw(data, clientObjz);
}
});
socket.on('end', function() {
game.removeClient(socket);
console.log('A client has disconnected');
});
socket.on('error', function(err) {
console.log(err);
});
});
server.listen(Game1, "localhost", function() {
console.log('Server is listening on port 6113');
});
}
//this code is another file as i am calling it by game.clients.push
addClient: function(client) {
if (client) {
self.clients.push(client);
}
}
Yes, it's a clubpenguin emulator
full code: https://github.com/dev3211/bingojs
You need to implement socket channels if you are doing this only with NodeJS net.createServer. If you want it simple, you could look for something using express.js, something like this: https://medium.com/factory-mind/websocket-node-js-express-step-by-step-using-typescript-725114ad5fe4
This question already has answers here:
socket.emit in a simple TCP Server written in NodeJS?
(3 answers)
Closed 5 years ago.
I am new to NodeJS and started to learn by building a simple command line chat application. I have the following code for Server and Client. Client-Server communication is successful but I am not able to capture 'adduser' event from the client. Please tell me where I am going wrong.
Server:
var net = require('net');
var chatServer = net.createServer(function(socket){
socket.pipe(socket);
}),
userName="";
chatServer.on('connection',function(client){
console.log("ChatterBox Server\n");
client.write("Welcome to ChatterBox!\n");
client.on('data',function(data){
console.log(""+data);
});
client.on('adduser',function(n){
console.log("UserName: "+ n);
userName = n;
});
});
chatServer.listen(2708);
Client:
var net = require('net');
var client = new net.Socket();
client.connect(2708,'127.0.0.1');
client.on('connect',function(){
client.emit('adduser',"UserName");
});
console.log("Client Connected!\n");
client.on('data',function(data){
console.log(""+data);
});
I guess you don't have to do from the client side :
client.connect(2708,'127.0.0.1');
Just write your client like this is sufficient.
var net = require('net');
var client = new net.Socket();
client.connect(2708, '127.0.0.1',function(){
console.log("Client Connected!\n");
client.emit('adduser',"UserName");
});
client.on('data',function(data){
console.log(""+data);
});
client.on('close', function() {
console.log('Connection closed');
});
So the server side :
var net = require('net');
var sockets = [];
var port = 2708;
var guestId = 0;
var server = net.createServer(function(socket) {
// Increment
guestId++;
socket.nickname = "Guest" + guestId;
var userName = socket.nickname;
sockets.push(socket);
// Log it to the server output
console.log(userName + ' joined this chat.');
// Welcome user to the socket
socket.write("Welcome to telnet chat!\n");
// Broadcast to others excluding this socket
broadcast(userName, userName + ' joined this chat.\n');
socket.on('adduser',function(n){
console.log("UserName: "+ n);
userName = n;
});
// When client sends data
socket.on('data', function(data) {
var message = clientName + '> ' + data.toString();
broadcast(clientName, message);
// Log it to the server output
process.stdout.write(message);
});
// When client leaves
socket.on('end', function() {
var message = clientName + ' left this chat\n';
// Log it to the server output
process.stdout.write(message);
// Remove client from socket array
removeSocket(socket);
// Notify all clients
broadcast(clientName, message);
});
// When socket gets errors
socket.on('error', function(error) {
console.log('Socket got problems: ', error.message);
});
});
// Broadcast to others, excluding the sender
function broadcast(from, message) {
// If there are no sockets, then don't broadcast any messages
if (sockets.length === 0) {
process.stdout.write('Everyone left the chat');
return;
}
// If there are clients remaining then broadcast message
sockets.forEach(function(socket, index, array){
// Dont send any messages to the sender
if(socket.nickname === from) return;
socket.write(message);
});
};
// Remove disconnected client from sockets array
function removeSocket(socket) {
sockets.splice(sockets.indexOf(socket), 1);
};
// Listening for any problems with the server
server.on('error', function(error) {
console.log("So we got problems!", error.message);
});
// Listen for a port to telnet to
// then in the terminal just run 'telnet localhost [port]'
server.listen(port, function() {
console.log("Server listening at http://localhost:" + port);
});
So you've got an object "users" inside the "user" when is connected, push user to the array users but you need to do (server side) on('close', ... to remove the user from users when connected is false ... etc
I have the following example of listening to connection and data events, to echo the result back to other telnet clients listening on port 8888. My telnet sessions connect to locahost fine, but no output is echoed. I am hitting my head against a brick wall trying to figure out what is wrong. The execution doesn't even get as far as the 'connect' event.
/server.js
var events = require('events');
var net = require('net');
var channel = new events.EventEmitter();
channel.clients = {};
channel.subscriptions = {};
channel.on('join', function (id, client) {
this.clients[id] = client;
this.subscriptions[id] = function (senderId, message) {
if (id != senderId) {
this.clients[id].write(message);
}
}
this.on('broadcast', this.subscriptions[id]);
});
var server = net.createServer(function (client) {
var id = client.remoteAddress + ':' + client.remotePort;
console.log(id);
client.on('connect', function () {
console.log('A new connection was made');
channel.emit('join', id, client);
});
client.on('data', function (data) {
data = data.toString();
channel.emit('broadcast', id, data);
});
});
server.listen(8888);
I then run in the command line
node server.js
telnet 127.0.0.1 8888
When the callback to net.createServer is called, that's because of an implicit connection event. So your code should look like this:
var server = net.createServer(function (client) {
// when this code is run, the connection has been established
var id = client.remoteAddress + ':' + client.remotePort;
console.log('A new connection was made:', id);
channel.emit('join', id, client);
client.on('data', function(data) {
...
});
client.on('end', function() {
...
});
});
The manual has this to say;
net.createServer([options], [connectionListener])
Creates a new TCP server. The connectionListener argument is automatically set as a listener for the 'connection' event.
In other words, your function (client) { already received the connection event, and adding a listener to it when it has already been dispatched has no further effect.
I am building a game using socketio.
The server stores the number of players, when it goes to 2, game start.
However, when I open two browser one by one, only the first one(not the latter one) receive the game start message.
Client side:
var socket = io.connect('http://localhost:8080');
socket.on('connected', function (data) {
$('#status').html('You are connected');
socket.emit('1 party connected');
});
socket.on('game start', function (data) {
$('#status').html('game start');
});
Server side:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(8080);
var connected_parties_no = 0;
io.sockets.on('connection', function (socket) {
socket.emit('connected', { hello: 'world' });
socket.on('1 party connected', function () {
connected_parties_no++;
console.log(connected_parties_no.toString()+' parties are connecting.');
if (connected_parties_no == 2) {
game_start(socket);
}
});
socket.on('disconnect', function () {
connected_parties_no--;
});
});
function game_start(socket) {
socket.broadcast.emit('game start');
}
socket.broadcast.emit('game start');
will send the 'game start' event to everyone except `socket. You're most likely looking for
io.sockets.emit('game start');