Node.js Printing input letter by letter - node.js

I have tried to build a chat server using node.js however it prints the input on other clients' consoles letter by letter, is there a way to keep it all together
var net = require('net')
var chatServer= net.createServer()
clientList = []
chatServer.on('connection', function(client){
client.name = client.remoteAddress + ":" + client.remotePort
client.write('Hi' + client.name + "!\n");
clientList.push(client)
client.on('data', function(data){
broadcast(data, client)
})
})
function broadcast(message, client){
for(var i=0; i<clientList.length;i+=1){
if(client !== clientList[i]){
clientList[i].write(client.name + " says" + message +"\n")
}
}
}
chatServer.listen(9000, "127.0.0.1")
Thanks.

You could do something like this if your messages are newline-delimited:
chatServer.on('connection', function(client) {
client.name = client.remoteAddress + ":" + client.remotePort;
client.write('Hi' + client.name + "!\n");
clientList.push(client)
var buf = '';
client.setEncoding('utf8');
client.on('data', function(data) {
buf += data;
var i;
while ((i = buf.indexOf('\n')) > -1) {
broadcast(buf.substring(0, i), client);
buf = buf.substring(i + 1);
}
});
});

Related

Get the list of connected users/client in Socket.io

I need to get a list of connected users or clients from socket.io for real time chat.
List of connected user image
I managed to display a list of client who connect to my route/API (localhost:3003/chat). Who ever access this route (authorize or not) will be displayed as shown in the picture. My problem is on initial access or if you try to refresh the browser the client will not see the currently connected users or history of client connections.
This is my sample code for socket.io for server side,
module.exports.initializeSocketIO = (io) => {
io.on('connection', (socket) => {
socket.on('connectedUser', (users) =>{
socket.name = users;
io.emit('connectedUser', users);
console.log(users + ' has joined the chat.');
});
socket.on('disconnect', (user) => {
io.emit('disconnect', user);
console.log(socket.name + ' has left the chat.');
});
socket.on('chatMessage', (from, msg) => {
io.emit('chatMessage', from, msg);
console.log('Message From: ' + from + '\n -' + msg);
});
socket.on('showTypingUser', (user) => {
io.emit('showTypingUser', user);
});
});
};
This is my sample code for socket.io for client side
var socket = io();
socket.on('connectedUser', function(users){
var name = $('#currentUser').val();
var me = $('#user').val(name);
socket.name = users;
if(users != me){
$('#connectedUser').append('<tr><td>' + '<b>' + users + '</b>' + ' has
joined the discussion. </td></tr>' );
}
});
socket.on('chatMessage', function(from, msg){
var me = $('#user').val();
var color = (from == me) ? 'green' : '#009afd';
var from = (from == me) ? 'Me' : from;
var date = new Date();
if(from == "Me"){
$('#messages').append('<div class="speech-bubble">' + '<b style="color:' + color + '">' + from + ':</b> ' + msg + ' <span class="pull-right" style="color:gray">' + date.toLocaleString() + '</span>' +'</div>');
} else {
$('#messages').append('<div class="speech-bubble-reply">' + '<b
style="color:' + color + '">' + from + ':</b> ' + msg + ' <span class="pull-right" style="color:gray">' + date.toLocaleString() + '</span>' +'</div>');
}
});
socket.on('showTypingUser', function(user){
var name = $('#currentUser').val();
var me = $('#user').val(name);
if(user != me) {
$('#notifyUser').text(user + ' is typing ...');
}
setTimeout(function(){ $('#notifyUser').text(''); }, 10000);;
});
socket.on('disconnect', function(user){
var name = $('#currentUser').val();
var me = $('#user').val(name);
if(socket.name != name){
$('#connectedUser').append('<tr><td>' + '<b>' + socket.name + '</b>' + ' has left the discussion. </td></tr>' );
}
});
$(document).ready(function(){
var name = $('#currentUser').val();
$('#welcomeMessage').append('<div class="welcome-chat">Welcome to Entrenami Chat</div>')
socket.emit('connectedUser', name);
});
NOTE: I'm using express for my route and controller and EJS for my view. I'm a bit stuck here because I don't know where to look on how to solve my problem.
io.engine.clientsCount return the total count of connected users you can send it to client when a user get connected like this:
io.on('connection', (socket) => {
var total=io.engine.clientsCount;
socket.emit('getCount',total)
});

Merging a HTTP Server and a Net Server in Node.js

For a school project we had to develop a file server and also a chat server. I did both in Node.js. Now I have to merge them, but they're both supposed to listen on the same port.
I have two file which both work. The chat server uses
net.createServer(function (socket){
...
}}).listen(9020);
And the file server uses
http.createServer(function (request, response){
...
}}).listen(9020);
Simple putting all the code in the same file returns an error since you can't have two servers listening on the same port. What's the best way to merge them? Can all the code be run in either the Net or HTTP server? I've tried this but it isn't working for me.
Here's the full code:
chat.js
// Load the TCP Library
net = require('net');
// Keep track of the chat clients
var clients = [];
var chat = [];
// Start a TCP Server
net.createServer(function (socket) {
socket.setEncoding('utf8');
// Identify this client
socket.name = "unknown"
// Put this new client in the list
clients.push(socket);
// Send a nice welcome message and announce
socket.write("Welcome to Michael's chat room" + "\r\n");
//broadcast(socket.name + " joined the chat\r\n", socket);
// Handle incoming messages from clients.
socket.on('data', function (data) {
var textdata = data.toString();
if(textdata.trim() === "adios"){
broadcast("closing connection", socket);
socket.end();
}
else if (textdata.trim() === "help"){
broadcast("*******************Available commands:*******************\r\nhelp Display the program options\r\ntest: <words> Send a test message of <words> that does not get logged\r\nname: <chatname> Set name to <chatname>\r\nget Get the entire chat log\r\npush: <stuff> Add <stuff> to the chat log\r\ngetrange <startline> <endline> Get contents of the chat log from <startline> to <endline>\r\nadios Close connection");
}
else if (startsWith(textdata, "name:")){
var rmv = "name: ";
textdata = textdata.slice( textdata.indexOf( rmv ) + rmv.length );
socket.name = textdata.trim();
broadcast("OK\r\n", socket);
}
else if (startsWith(textdata, "push:")){
var rmv = "push: ";
textdata = textdata.slice( textdata.indexOf( rmv ) + rmv.length );
textdata = textdata.trim();
chat.push(socket.name + ": " + textdata + "\r\n");
broadcast("OK\r\n");
}
else if (startsWith(textdata, "test:")){ //Why do we even have this lever?
var rmv = "test: ";
textdata = textdata.slice( textdata.indexOf( rmv ) + rmv.length );
broadcast(textdata.trim() + "\r\n");
}
else if (textdata.trim() === "get"){
for (var i = 0; i < chat.length; ++i) {
//if (i < 1){
// broadcast(chat[i].toString(), socket);
//}
//else{
broadcast(chat[i].toString(), socket);
//}
}
}
else if (startsWith(textdata, "getrange")){
var rmv = "getrange ";
textdata = textdata.slice( textdata.indexOf( rmv ) + rmv.length );
var newtextdata = textdata;
newtextdata = newtextdata.split(" ");
var stringArray = new Array();
for(var i =0; i < newtextdata.length; i++){
stringArray.push(newtextdata[i]);
if(i != newtextdata.length-1){
//stringArray.push(" ");
}
}
for (var i = stringArray[0]; i <= stringArray[1]; ++i) {
broadcast(chat[i].toString() + "\r\n", socket);
}
}
else{
broadcast("Error: unrecognized command: " + textdata + "\r\n", socket);
}
});
// Remove the client from the list when it leaves
socket.on('end', function () {
clients.splice(clients.indexOf(socket), 1);
broadcast(socket.name + " left the chat.\r\n");
});
// Send a message to all clients
function broadcast(message, sender) {
clients.forEach(function (client) {
// Don't want to send it to sender
///if (client === sender) return; //actually want to send a lot of stuff only to sender - how to do this?
client.write(message);
});
// Log it to the server output too
process.stdout.write(message)
}
function startsWith(str, word) {
return str.lastIndexOf(word, 0) === 0;
}
socket.on('Error', function(err){
console.log("well heck, there's been an error")
});
}).listen(9020);
// Put a friendly message on the terminal of the server.
console.log("Chat server running at port 9020\r\n");
file.js
//based heavily off of https://developer.mozilla.org/en-US/docs/Node_server_without_framework
var http = require('http');
var fs = require('fs');
var path = require('path');
http.createServer(function (request, response) {
console.log('request ', request.url);
var filePath = '.' + request.url;
if (filePath == './')
filePath = './index.html';
if (filePath == './CHAT')
filePath = './chatform.html';
var extname = String(path.extname(filePath)).toLowerCase();
var contentType = 'text/html';
var mimeTypes = {
'.html': 'text/html',
'.js': 'text/javascript',
'.css': 'text/css',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpg',
'.gif': 'image/gif',
};
contentType = mimeTypes[extname] || 'application/octect-stream';
fs.readFile(filePath, function(error, content) {
if (error) {
if(error.code == 'ENOENT'){
fs.readFile('./404.html', function(error, content) {
response.writeHead(200, { 'Content-Type': contentType });
response.end(content, 'utf-8');
});
}
else {
response.writeHead(500);
response.end('Sorry, check with the site admin for error: '+error.code+' ..\n');
response.end();
}
}
else {
response.writeHead(200, { 'Content-Type': contentType });
response.end(content, 'utf-8');
}
});
}).listen(9020);
console.log('Server running on port 9020');

Nodejs - data transfer between server and client

I was given a task to send JSON string from client to server and from server to client, whenever there is a new record found to send.
I decided to build TCP connection(suggest me if there is any other better way in Node.js) between server and client to transfer data.
The problem is, I was supposed to use a delimiter to separate JSON strings one from another. I am afraid what if the json string contains the delimiter string inside the object. I am looking for a better way to separate two JSON strings.
Below is my code. Please help me.
Client
var net = require('net')
, client = new net.Socket();
var chunk = ''
, dlim_index = -1
, delimit = '~~';
client.connect(config.Port, config.IpAddress, function () {
console.log('Server Connected');
client.write('CLIENTID:' + process.argv[2]);
client.write(delimit);
});
client.on('data', function (data) {
var recvData = data.toString().trim();
chunk += recvData;
dlim_index = chunk.indexOf(recvData);
console.log(data);
while (dlim_index > -1) {
var useData = chunk.substring(0, dlim_index);
if (useData == 'SUCCESS') {
controller.listenOutQueue(function (dataToSend) {
var object = JSON.parse(dataToSend);
client.write(dataToSend);
client.write(delimit);
});
}
else {
var record = JSON.parse(useData);
controller.insertIntoQueue(record, function (status) {
});
}
chunk = chunk.substring(dlim_index + 2);
dlim_index = chunk.indexOf(delimit);
}
});
client.on('close', function () {
console.log('Connection closed');
});
client.setTimeout(50000, function () {
//client.destroy();
});
Server
var net = require('net')
, server = net.createServer()
, delimit = '~~'
, clients = [];
controller.listenOutQueue(function (dataToSend) {
client.write(dataToSend);
client.write(delimit);
});
server.on('connection', function (socket) {
var chunk = '';
var dlim_index = -1;
socket.on('data', function (data) {
var recvData = data.toString().trim();
chunk += recvData;
dlim_index = chunk.indexOf(delimit);
while (dlim_index > -1) {
var useData = chunk.substring(0, dlim_index);
if (useData.substring(0, 9) == 'CLIENTID:') {
socket.clientid = useData.replace('CLIENTID:', '');
console.log('Client Id: ' + socket.clientid);
clients.push(socket);
var successMessage = "SUCCESS";
socket.write(successMessage);
socket.write(delimit);
}
else {
controller.insertIntoQueue(JSON.parse(useData), function (status) {
});
}
chunk = chunk.substring(dlim_index + 2);
dlim_index = chunk.indexOf(delimit);
}
});
socket.on('end', function () {
console.log('Connection Closed (' + socket.clientid + ')');
});
socket.on('error', function (err) {
console.log('SOCKET ERROR:', err);
});
});
server.listen(config.Port, config.IpAddress);

Node.js how to handle packet fragmentation with net.Server

When a net.Server receives data that exceeds 1500 bytes (default mtu), the 'on data' event is executed with each fragment of the packet. Is there a way to receive the whole packet in a single 'on data' call?
Thanks.
Try this
var sys = require('sys');
var net = require('net');;
var socktimeout = 600000;
var svrport = your_port;
var svr = net.createServer(function(sock) {
var mdata = new Buffer(0);
//sys.puts('Connected: ' + sock.remoteAddress + ':' + sock.remotePort);
sock.setTimeout(socktimeout,function(){
sock.end("timeout");
sock.destroy();
});
sock.on('data', function(data) {
if(mdata.length != 0)
{
var tempBuf = Buffer.concat([mdata, data]);
mdata = tempBuf;
}
else
{
mdata = data;
}
var len=got_your_Packget_length(mdata);
if(mdata.length == len)
{
do_your_job(mdata)
mdata = new Buffer(0);
}
});
sock.on('error', function(err) { // Handle the connection error.
sys.puts('error: ' + err +'\n');
});
});
svr.listen(svrport);

How to create a node js server socket to receive data in different ports?

I need a socket server that must receive data from 100 clientes in different ports on the server. I've created an array of server sockets and I don't know if this is correct.
I also identified a slowness to receive the data when I have about 100 clients sending data and for some reason the server stops receiving from 10 clients.
Here is my code for 3 ports as an example.
var net = require('net');
var rl = require('readline');
var fs = require('fs');
var ports = [60001, 60002, 60003];
var server = new Array();
ports.forEach(function(value) {
server[value] = net.createServer(function (socket) { // array of socket servers
socket.on('error', function(err) {
console.log(err.stack);
server[value].close();
server[value].listen(value); //start listen again
});
socket.on('end', function() {
console.log('client disconnected: ' + value);
server[value].close();
server[value].listen(value); //start listen again
});
console.log('client connected: ' + value);
var intf = rl.createInterface(socket, socket);
intf.on('line', function (line) {
fs.exists(__dirname + "\\file" + value.toString() + ".txt", function (exists) {
if(exists){
var stream = fs.createWriteStream(__dirname + "\\file" + value.toString() + ".txt", {'flags': 'a'});
} else {
var stream = fs.createWriteStream(__dirname + "\\file" + value.toString() + ".txt", {'flags': 'w'});
}
try {
stream.once('open', function(fd) {
console.log(value.toString() + " - " + line);
stream.write(line + "\r\n");
stream.end();
});
} catch (x) {
console.log(x.stack);
}
});
});
});
server[value].listen(value); // listen many ports
});

Resources