how to flush the buffer in TCP connection - node.js

Hi I am facing issue with a server client message passing from web client to TCP server . Every time I reconnect to the web page my first 6 messages passes with out delay and the seventh message takes lots of time and the first message repeats again. I think there should be some handler for buffer but I have no idea of how to start it. Help me to solve this. My server and client both are in node socket ( using var net = require('net') ).

my client has to send a response for the ajax call which i made from web page:
$.ajax({
type: 'POST',
url: 'http://localhost:3000/client',
dataType: "json",
contentType: "application/json; charset=UTF-8",
data: JSON.stringify({name:data+'\r'}),// this is the data i get from web page
done : function(data){
console.log('on success', data);
},
fail : function(error){
console.log('on error', error)
}
})
and my node client
var net = require('net');
var _ = require('lodash');
router.post('/client', function(req, res) {
var inputJSON = req.body;
var HOST = '127.0.0.1';
var PORT = 5000;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
// Write a message to the socket as soon as the client is connected, the server will receive it as message from the client
_.forEach(inputJSON, function(value,key){
client.write(value);
// console.log(value);
})
});
//This is the line i missed in my earlier program the client should respond
res.send('success')
});
I am learning node. so you can improvise my code with your comments so i can improve better thanks.

Related

connect cmd line socket server via nodejs socket.io

I have a node.js server communicating to a client web page, sending it message. This is working great based on the many tutorials and searching stack overflow :)
Where I am having an issue is when I attempt to startup a separate socket connection to a 3rd party cmd line executable instance runs as a socket server. The 3rd party executable does not adhere to the socket.io namespace/room type of events, so I read that socket.io-events may help where instead of:
socket.on('some key', function(){/**do stuff*/}); I could:
eventRouter.on('*', function(){/*do stuff*/});
For this communication, I am assuming I need to use socket.io-client on the node.js side in order to talk to the cmd executable, but I am getting exceptions trying to do a socket2.use(router); where socket2 is my socket.io-client and router is the socket.io-events object.
All runs on localhost, node to web page is port 8001 and node.js to executable is on port 8002. Please pardon the code, for I have been trying to get this to work for a few days and is a bit ugly now.
The cmd executable to execute and its arguments I have coming from the web page which works. I am able to start the exe. The EXE expects a ACK on each message sent, thus why you see the code emitting it back.
I have a interval where I set and update an element on the web page. I have another element that I set messages (msg).
var http = require('http');
var url = require('url');
var fs = require('fs');
var server;
server = http.createServer(function(req, res){
// your normal server code
var path = url.parse(req.url).pathname;
switch (path){
case '/':
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<h1>Hello! Try the Test page </h1>');
res.end();
break;
case '/socket.html':
fs.readFile(__dirname + path, function(err, data){
if (err){
return send404(res);
}
res.writeHead(200, {'Content-Type': path == 'json.js' ? 'text/javascript' : 'text/html'});
res.write(data, 'utf8');
res.end();
});
break;
default: send404(res);
}
}),
send404 = function(res){
res.writeHead(404);
res.write('404');
res.end();
};
server.listen(8001);
var str = "ack0";
var bytes = [];
for (var i = 0; i < str.length; ++i) {
bytes.push(str.charCodeAt(i));
}
// use socket.io
var io = require('socket.io').listen(server);
// define interactions with client
io.sockets.on('connection', function(socket){
//send data to client
setInterval(function(){
socket.emit('date', {'date': new Date()});
}, 1000);
//recieve client data
socket.on('client_data', function(data){
var spawn = require('child_process').spawn;
console.log('pre-spawned');
spawn(data.cmd, data.args, {});
setTimeout(function() {
console.log('hello world!');
}, 1000);
var aptIO = require('socket.io-client');
var router = require('socket.io-events')();
var socket2 = aptIO.connect('localhost:8002', {reconnect: true});
router.on('connection', function(s){
//send data to client
console.log('apt');
router.on('*', function(sock, args, next){
var name = args.shift(), msg = args.shift();
console.log(name + " " + JSON.stringify(msg));
sock.emit(bytes);
io.sockets.emit('msg', {'msg': JSON.stringify(msg)})
next();
});
s.emit(bytes);
});
console.log('spawned');
// getting runtime exceptions here...have tried various things...
socket2.use(router);
});
});
With the help from JGreenwell, I was able to resolve me issue.
I ended up having the node server communicate to the client html page via socket.io connection for messages. The node server would launch the cmd line executable providing it the port to connect to which is different from the socket.io port used.
Once started, the executable would communicate with the server via the net module. The server would just pass the information on to the socket.io connection. the js in the html page knows how to parse the message in order to increment the progress bar and list the messages in a text area control.
I took it even further by having the messages be broadcast-ed to multiple clients on the socket.io connection.

callback on net.createServer() is called twice

I'm following the tutorial on this tutorial. Here's the code:
var net = require('net')
var chatServer = net.createServer()
chatServer.on('connection', function(client) {
client.write('Hi!\n');
client.write('Bye!\n');
console.log("got msg from http"); //added
client.end()
})
chatServer.listen(9000)
I placed a console.log between the bye and the client.end()
When I run it and hit port 9000, the console.log is outputed twice instead of once.
got msg from http
got msg from http
anyone know why?
Thanks
I'm guessing you're using a browser to test your server. What you're seeing is two different incoming HTTP requests. Try the following code and you will likely see that there are two incoming HTTP requests:
var net = require('net')
var chatServer = net.createServer()
chatServer.on('connection', function(client) {
client.write('Hi!\n');
client.write('Bye!\n');
console.log("got msg from http"); //added
client.on('data', function (data) {
console.log('data: \n%s', data)
});
client.end()
})
chatServer.listen(9000)
The two requests should be GET / and GET /favicon.ico, favicon.ico is the icon which is displayed on the browser tab and bookmarks etc.

Socket emits not sending from client (sending fine from server)

The following is a unit test to show the behavior that I'm experiencing, which I recognize as different than what I've experienced before. In essence, the way I was using sockets before (maybe two months ago) stopped working sometime between then and now. I'm not sure what happened. My previously working code has broken.
var socketio = require('socket.io');
var http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type' : 'text/html' });
var html = "<html><head><script src=\"/socket.io/socket.io.js\"></script>\
<script>var sock = io.connect();\
sock.on('sup', function(data) {\
console.log(\"whoo\");\
sock.emit('howdy', {'hi' : 'ho'});\
});</script></head></html>";
res.end(html);
}).listen(8080);
socketio.listen(server, {log:false}).on('connection', function(socket) {
socket.on('howdy', function(data){console.log("HI!");});
socket.emit("sup", {"hey" :"yo"});
});
What I would expect from the code is the following sequence of events:
socket connects, server emits "sup" message.
client receives "sup" message and logs "whoo"
client sends "howdy" message
server receives "howdy" message and logs "HI!"
Step 4 is not occurring at all. (and therefore I assume step 3 might not be happening, either)
What's going on?
Your client side code is essentially this
var sock = io.connect();
console.log("Gets here");
sock.on('sup', function(data) {
console.log("whoo");
});
sock.emit('howdy', {'hi' : 'ho'});
I'm assuming it will work if you just move the emit into the handler.
var sock = io.connect();
console.log("Gets here");
sock.on('sup', function(data) {
console.log("whoo");
sock.emit('howdy', {'hi' : 'ho'});
});
Or you can try listening for the connect event
var sock = io.connect();
console.log("Gets here");
sock.on('sup', function(data) {
console.log("whoo");
});
sock.on('connect', function() {
sock.emit('howdy', {'hi' : 'ho'});
});
I just updated socket.io, and it's working now.

How can I create a Twitter stream using Node.js and Websockets?

A few months ago (August 2011) I successfully created a node.js websockets server which connected to Twitter's Streaming API using basic HTTP user/password authentication. To do this, I employed Andre Goncalves' twitter-nodejs-websocket library.
Since creating this working implementation, Twitter has eliminated access to the streaming API via basic HTTP auth, in favor of OAuth. After this shift, I utilized Ciaran Jessup's node-oauth library, which has successfully given me access to the Streaming API again (when I run the server I am successfully outputting the tweets via console.log(tweet) -- see below ).
The problem now is that my websockets server is no longer working. When I run my server from the command line and hit the client web page from the browser, the websocket "onclose" event is immediately fired.
I've tried everything I can think of to get this working. Any help would be very greatly appreciated!
server.js
var sys = require('sys'),
http = require('http'),
ws = require("./vendor/ws"),
base64 = require('./vendor/base64'),
arrays = require('./vendor/arrays')
var OAuth = require('./oauth/oauth').OAuth;
var consumer_key = '[...]'; //removed for obvious security reasons...
var consumer_secret = '[...]';
var access_token = '[...]';
var access_token_secret = '[...]';
oa = new OAuth("https://twitter.com/oauth/request_token",
"https://twitter.com/oauth/access_token",
consumer_key,
consumer_secret,
"1.0A",
null,
"HMAC-SHA1");
var request = oa.get("https://stream.twitter.com/1/statuses/filter.json?track=google", access_token, access_token_secret );
// Response Parsing -------------------------------------------- //
var clients = [];
var message = "";
request.addListener('response', function (response) {
response.setEncoding('utf8');
response.addListener("data", function (chunk) {
message += chunk;
var newlineIndex = message.indexOf('\r');
// response should not be sent until message includes '\r'.
// Look at the section titled "Parsing Responses" in Twitter's documentation.
if (newlineIndex !== -1) {
var tweet = message.slice(0, newlineIndex);
clients.forEach(function(client){
// Send response to all connected clients
client.write(tweet);
});
// this just tests if we are receiving tweets -- we are: terminal successfully outputs stream //
var pt = JSON.parse(tweet);
console.log('tweet: ' + pt.text);
}
message = message.slice(newlineIndex + 1);
});
});
request.end();
// Websocket TCP server
ws.createServer(function(websocket){
clients.push(websocket);
websocket.addListener("connect", function(resource){
// emitted after handshake
sys.debug("connect: " + resource);
}).addListener("close", function(){
// emitted when server or client closes connection
clients.remove(websocket);
sys.debug("close");
});
}).listen(8081);
// This basic http server works, so we know this port is open.
//
// var http = require('http');
// http.createServer(function (req, res) {
// res.writeHead(200, {'Content-Type': 'text/plain'});
// res.end('Hello World\n');
// }).listen(8081);
client code
<script type="text/javascript" charset="utf-8">
ws = new WebSocket("ws://ec2-67-202-6-10.compute-1.amazonaws.com:8081");
ws.onmessage = function(evt) {
console.log('tweet')
};
ws.onclose = function() {
console.log("socket closed");
};
ws.onopen = function() {
console.log("connected...");
};
</script>
Maybe you updated the browser? The websocket spec is chaning rapidly. Anyway, I'd propose using socket.io because it will even still work with fallbacks if the browser is outdated or websockets got incompatible again or a crappy proxy is preventing websockets from working.
Have a look at this sample event stream (it uses server sent events) from a twitter stream:
https://github.com/chovy/nodejs-stream

cannot display my variable on browser

I am working on a socket.io + Node.js project.
When I print an variable using console.log, I get my variable on console.
But when I sent this variable to a client, it seems as [object Object] form on browser.
How can I see my variable on browser?
Thanks
Try console.log(JSON.stringify(myVariable)); and then look at it in your browser and you'll gain more insight as to what's happening exactly.
You may be using the 0.6 serverside syntax of:
socket.send({foo: 'bar'})
Try using the following updated syntax:
socket.json.send({foo: 'bar'})
You can find more information here:
https://github.com/LearnBoost/Socket.IO/wiki/Migrating-0.6-to-0.7
thanks, console.log(JSON.stringify(myVariable)); worked for my case. Variable has shown as
{ coloumn_that_result_lays: "result"}. Of course we can overcome it with javascript-substring but is there a function which gives "result" directly.
// Require HTTP module (to start server) and Socket.IO
var io = require('socket.io'),
http = require('http');
io = require('socket.io');
// Start the server at port 8080
var server = http.createServer(function(req, res){
// Send HTML headers and message
res.writeHead(200,{ 'Content-Type': 'text/html' });
res.end('<h1>Hello Socket Lover!</h1>');
});
server.listen(8080);
// Create a Socket.IO instance, passing it our server
var socket = io.listen(server);
// Add a connect listener
socket.on('connection', function (client){
//mysql
var mysql = require('db-mysql');
new mysql.Database({
hostname: 'localhost',
user: 'root',
password: '123123',
database: 'node'
}).connect(function(error) {
if (error) {
return console.log('CONNECTION error: ' + error);
}
this.query('SELECT data FROM exam where id=2 ').
execute(function(error,result) {
if (error) {
console.log('ERROR: ' + error);
return;
}
client.json.send(JSON.stringify(result));
});
});
// Create periodical which ends a message to the client every 5 seconds
var interval = setInterval(function() {
client.send('This is a message from the server! ' );
},1000);
// Success! Now listen to messages to be received
client.on('message',function(event){
console.log('Received message from client!',event);
});
client.on('disconnect',function(){
clearInterval(interval);
console.log('Server has disconnected');
});
});

Resources