I'm configuring a nodejs server in order to use it as a server for push notifications.
I have this code:
io.sockets.on('connection', function(socket) {
console.log(socket);
// watching the xml file
fs.watchFile('client.xml', function(curr, prev) {
// on file change we can read the new xml
fs.readFile('client.xml', function(err, data) {
if (err)
throw err;
// parsing the new xml datas and converting them into json file
parser.parseString(data);
});
});
// when the parser ends the parsing we are ready to send the new data to the
// frontend page
parser.addListener('end', function(result) {
socket.volatile.emit('notification', result);
});
});
On server. And on client this one:
<script>
function test(data) {
console.log(data);
jQuery('#' + data.id).html(data.content);
}
</script>
<script>
// creating a new websocket
var socket = io.connect('http://10.0.0.113:8000');
// on every message recived we print the new datas inside the #container div
socket.emit('data', {id : 'id'});
socket.set('nickname', {id : 'test'});
socket.on('notification', function(data) {
_efbn(data.callback, window, data.response, data);
});
/**
* Función que ejecuta una función por nombre. Puede usar namespaces
* (algo.algo.algo.funct)
*
* #see http://stackoverflow.com/questions/359788/javascript-function-name-as-a-string/359910#359910
*/
function _efbn(functionName, context) {
var args = Array.prototype.slice.call(arguments);
args = [ args[2], args[3] ]; // Fix para IE.
var namespaces = functionName.split(".");
var func = namespaces.pop();
for ( var i = 0; i < namespaces.length; i++) {
context = context[namespaces[i]];
}
try {
if (typeof context[func] == 'function') {
return context[func].apply(this, args);
}
} catch (e) {
console.log(e);
}
return null;
}
</script>
Everything is working as I wish. However, I want to send something like:
socket.set('site', '12345');
socket.set('object', 'ABCDE');
In order to identify which xml should I be listening, instead of being listening allways to client.xml.
How can I do it? I have this on server.js:
id = require('url').parse(req.url, true).query.id;
But, since server its only executed when the connection is open, but no when the socket is open, if the connection between the client and the server fails, when jquery retries to open the socket, id will be null...
I would do this instead on the server,
io.sockets.on('connection', function(socket) {
console.log(socket);
socket.on('setup', function(config) {
// use your connection specific config variables like
var id = config.id; // and then use id in your logic below.
// watching the xml file
fs.watchFile('client.xml', function(curr, prev) {
// on file change we can read the new xml
fs.readFile('client.xml', function(err, data) {
if (err)
throw err;
// parsing the new xml datas and converting them into json file
parser.parseString(data);
});
});
// when the parser ends the parsing we are ready to send the new data to the
// frontend page
parser.addListener('end', function(result) {
socket.volatile.emit('notification', result);
});
});
});
And on the client-side,
// creating a new websocket
var socket = io.connect('http://10.0.0.113:8000');
socket.on("connect", function() {
// Setup your connection on the server-side by providing it
// some config variables.
var config = {
id: "id",
nickname: "test"
};
socket.emit("setup", config);
// on every message recived we print the new datas inside the #container div
socket.on('notification', function(data) {
_efbn(data.callback, window, data.response, data);
});
});
This way, whenever a new connection is established, the setup event is first called on the server with the required config variables.
Related
I am very beginner in NodeJS, I am taking data from S71200 PLC device using nodes7 library, I want to pass data using socket io emit but I can't pass data to socket io emit below my code
app.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var nodes7 = require('nodes7'); // This is the package name, if the repository is cloned you may need to require 'nodeS7' with uppercase S
var conn = new nodes7;
var doneReading = false;
var doneWriting = false;
var variables = {
TEST7: 'DB1,INT2.3',
TEST1: 'DB1,X0.0.3',
TEST2: 'DB1,INT2'
};
conn.initiateConnection({port: 102, host: '127.0.0.1', rack: 0, slot: 1}, connected);
function connected(err) {
if (typeof(err) !== "undefined") {
// We have an error. Maybe the PLC is not reachable.
console.log(err);
process.exit();
}
conn.setTranslationCB(function(tag) {return variables[tag];}); // This sets the "translation" to allow us to work with object names
conn.addItems(['TEST7','TEST1']);
//conn.writeItems('TEST2', 90, valuesWritten);
setInterval(function(){
conn.readAllItems(valuesReady);
},1000)
}
function valuesReady(anythingBad, values) {
if (anythingBad) { console.log("SOMETHING WENT WRONG READING VALUES!!!!"); }
console.log(values.TEST1[0],values.TEST1[1],values.TEST1[2],values.TEST7[0],values.TEST7[1],values.TEST7[2]);
//console.log( typeof(temp));
doneReading = true;
}
function valuesWritten(anythingBad) {
if (anythingBad) { console.log("SOMETHING WENT WRONG WRITING VALUES!!!!"); }
console.log("Done writing.");
doneWriting = true;
}
io.on('connection',function(socket){
console.log('one user connected '+socket.id);
socket.emit("channelname", {
message: "Passing S71200 data"
});
socket.on('disconnect',function(){
console.log('one user disconnected '+socket.id);
});
})
http.listen(3000,function(){
console.log('server listening on port 3000');
})
I am using interval function because every second data fetch from PLC device, I got all data from values.TEST1[0],values.TEST1[1],values.TEST1[2],values.TEST7[0],values.TEST7[1],values.TEST7[2] this data passing to
io.on('connection',function(socket){
console.log('one user connected '+socket.id);
socket.emit("channelname", {
message: "Passing S71200 data"
});
socket.on('disconnect',function(){
console.log('one user disconnected '+socket.id);
});
})
Help me to solve this problem
I am new with the node js.
I am using node js with express.
I am create connection on server side via below code.
io.sockets.on('connection', function (socket) {
// console.log('A new socket connected with id : '+socket.id);
socket.on('error',function(e){
// console.log(e);
})
socket.on('disconnect',function(e){
// console.log( " \n disconnect \n ",e);
})
socket.on('UserRoom', function(data){
var user_id = data.user_id;
if(socket.adapter.rooms[user_id]===undefined)
{
console.log('Hey i am connected to server for User id => '+user_id);
socket.join(user_id);
}
else
{
console.log('Hey i am already connected to User id');
}
});
socket.on('JoinDraft', function(data)
{
var game_unique_id = data.game_unique_id;
socket.join(game_unique_id);
});
});
app.post('/game_update', function(req, res)
{
var target = true;
var response = '';
req.on('data', function (data) {
response += data;
});
req.on('end', function () {
res.sendStatus(200);
var result = JSON.parse(response);
game_update(result);
});
});
function game_update( result )
{
var game_unique_id = result ;
io.to(game_unique_id).emit('game_update', {"game_unique_id": game_unique_id});
};
client side code :- for joining room
function joinDraft_socket() {
// console.log(gameObj);
socket.emit('JoinDraft',{"game_unique_id" : gameObj.game_unique_id});
}
for getting node response , we have
socket.on('game_update', function(data) {
if(data.game_unique_id == gameObj.game_unique_id) {
console.log('Trigger to update ', data);
isYourPick();
}
});
Server node emit data single time to any room ( game_unique_id) then clients are receiving server ping multiple times.
Please let me know if any one face this kind of issue and how they resolved it.
Below is image of console after single update of server node , client receive multiple hits
Any help is appreciate ...
Thanks in Advance
this is my code ----
var nsq = require('nsqjs');
var r = require('rethinkdb');
var nsqvar = (process.env.NSQD_RETH || "localhost:4161").split(",");
var p = r.connect({host:'localhost', port:8080, db:'test', authKey:''});{
p.then(function(conn) {
console.log("Succesfull connection")
}).error(function(error) {
console.log("Error at connection")
})
// Event Reader functionality inside connect callback
var eventreader;
eventreader = new nsq.Reader('hello_topic', 'hello_channel', {
lookupdHTTPAddresses: nsqvar
});
eventreader.connect();
eventreader.on('message', function (msg) {
// Now we have access to the connection
r.table('sprinkle_nsq_test').insert(msg.json()).run(conn);
console.log('Received message [%s]: %s', msg.id, msg.body.toString());
msg.finish();
console.log(msg);
});
}
And from the terminal I am trying to insert
curl -d '{"id": "712", "name": "Douglas Adams""type "casdasdasomedy"}' 'http://127.0.0.1:4151/put?topic= hello_topic'
At nsq at receives the message but at nodejs program at says throw new Error("Invalid JSON in Message");
^
Error: Invalid JSON in Message
and also at same time the message is not storing at rethinkdb.
Looks like the error message is correct - your JSON is invalid.
Try copying and pasting it through an online JSON validator / viewer and it will be invalid.
I've cleaned it up below. Hope it all works now.
{"id": "712", "name": "Douglas Adams", "type": "casdasdasomedy"}
You have some mistakes in your code (in regards to RethinkDB at least). Here is a fixed solution with comments (this may or may not fix your problem):
var nsq = require('nsqjs');
var r = require('rethinkdb');
var nsqvar = (process.env.NSQD_RETH || "localhost:4161").split(",");
// Connect to the client driver port 28015
var p = r.connect({ host:'localhost', port:28015, db:'test' });
p.then(function(conn) {
// Wait until the database is connected
console.log("Succesfull connection");
// Event Reader functionality inside connect callback
var eventreader;
eventreader = new nsq.Reader('hello_topic', 'hello_channel', {
lookupdHTTPAddresses: nsqvar
});
eventreader.connect();
eventreader.on('message', function (msg) {
// Make sure msg.json() is actually valid json
if (typeof msg === 'object' && msg !== null) {
throw new TypeError('`msg` is already and object. It doesnt need to be convert to json');
}
var json = msg.json();
if (typeof json !== 'object' && msg !== null) {
throw new TypeError('`msg.json()` is not an object and cant be inserted into the database.');
}
// Now we have access to the connection
r.table('sprinkle_nsq_test').insert(msg.json()).run(conn)
.then(function () {
// Wait until RethinkDB is done inserted the message to call `.finish`
console.log('Received message [%s]: %s', msg.id, msg.body.toString());
msg.finish();
console.log(msg);
});
});
}).error(function(error) {
console.log("Error at connection to the database");
});
I am a beginner in node.js. I am trying to create a webapp using node.js which will create servers in cloud and manage them. After doing some research I've decided to use node.js, socket.io, express and pkgcloud modules to create the webapp. Now, the problem I am facing is that I am unable to send messages to the front-end/client-side when a server is getting created. The server is getting created successfully but I am not getting how to send the server status to the browser screen.
Here's the code:
index.js
var express = require('express'),
app = express();
app.use(express.static(__dirname + '/'));
var io = require('socket.io').listen(app.listen(1337));
io.sockets.on('connection', function(socket) {
socket.on('mesg_to_server', function(data) {
// This is for testing whether we're receiving msgs on client side
io.sockets.emit("mesg_to_client",{ mesg: data["mesg"], mesg1: data["mesg1"] });
var Rackspace = require('./ex_rackspace');
var rackspace = new Rackspace();
rackspace.create(data.mesg);
});
});
ex_rackspace.js:
var pkgcloud = require('pkgcloud'),
_ = require('./node_modules/pkgcloud/node_modules/underscore');
var client = pkgcloud.providers.rackspace.compute.createClient({
username: 'xxxx',
apiKey: 'xxxxx',
region: 'HKG'
});
// This function will handle our server creation,
// as well as waiting for the server to come online after we've
// created it.
function handleServerResponse(err, server) {
if (err) {
console.dir(err);
return;
}
console.log('SERVER CREATED: ' + server.name + ', waiting for active status');
// Wait for status: ACTIVE on our server, and then callback
server.setWait({ status: server.STATUS.running }, 5000, function (err) {
if (err) {
console.dir(err);
return;
}
console.log('SERVER INFO');
console.log(server.name);
console.log(server.status);
console.log(server.id);
console.log('Make sure you DELETE server: ' + server.id +
' in order to not accrue billing charges');
});
}
var Rackspace = function() {
};
Rackspace.prototype.test = function (text) {
console.log("provider: Rackspace: " + text);
}
// first we're going to get our flavors
Rackspace.prototype.create = function (server) {
client.getFlavors(function (err, flavors) {
if (err) {
console.dir(err);
return;
}
// then get our base images
client.getImages(function (err, images) {
if (err) {
console.dir(err);
return;
}
var flavor = _.findWhere(flavors, { name: '1 GB Performance' });
var image = _.findWhere(images, { name: 'CentOS 5 (PV)' });
// Create our first server
client.createServer({
name: server,
image: image,
flavor: flavor
}, handleServerResponse);
});
});
}
module.exports = Rackspace;
page.html (client-side):
<!DOCTYPE html>
<html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
// our socket.io code goes here
var socketio = io.connect("127.0.0.1:1337");
socketio.on("mesg_to_client", function(data) {
document.getElementById("chatlog").innerHTML = ("<hr/>" +
data.mesg + ' ' + data.mesg1 + document.getElementById("chatlog").innerHTML);
});
socketio.on("test_output", function(data) {
console.log(data.mesg);
});
function sendMessage() {
var msg = document.getElementById("mesg_input").value;
socketio.emit("mesg_to_server", { mesg : msg, mesg1 : "here"});
}
</script>
</head>
<body>
<input type="text" id="mesg_input"/>
<button onclick="sendMessage()">Create</button>
<div id="chatlog"></div>
</body>
</html>
You need to add a callback to the create function
Rackspace.prototype.create = function (server, callback){
//your code - if err send error else send success message
callback(err, message)
}
Then use it when you call create
rackspace.create(data.mesg, function (err, message){
//your code with your socket emit here
});
I've tried to save a image to a specified directory with node.js using express.js and socket.io but it doesnt work.
On the client-side:
var reader = new FileReader();
function drop(e) {
e.stopPropagation();
e.preventDefault();
var dt = e.dataTransfer;
var files = dt.files;
jQuery.each(files, function(){
reader.onload = function(e) {
socket.emit('sendfile', e.target.result);
};
});
return false;
}
The image should be uploaded by a drag and drop function.
Then on the server-side:
io.sockets.on('connection', function (socket) {
[...]
socket.on('sendfile', function (data) {
var fs = require('fs');
app.use(express.bodyParser({ keepExtensions: true, uploadDir: '/uploaded' }));
io.sockets.emit('updatechat', socket.username, data); //test
});
I have also tried
socket.on('sendfile', function (data) {
var fs = require('fs');
fs.writeFile('/uploaded/test.png', data, "binary" , function (err) {
if (err) throw err;
console.log('It\'s saved!');
});
io.sockets.emit('updatechat', socket.username, data); //data test
});
but it doesnt saved anything.
The "data test" shows me, that the data are already were arrived on the server, so I don't think, that the problem comes from the client-side, but on the server-side I have no idea what I doing wrong
I made a simple example to illustrate the usage of file upload via socket!
The steps following are:
Create the send-file socket.io event to receive the file on app.js. This file received is a binary one;
In the jade/HTML page put an input file and a button to send it. NOTE: you don't have to use multipart to send a post with multipart content, we are sending socket files not a TCP request/response;
Initialize HTML5 File API support and prepare the listeners to watching out your file input component;
The rest of remaining routines to read the file and sent it content forward.
Now first step (app.js):
var io = require('socket.io').listen(8000, {log: false});
io.sockets.on('connection', function(socket) {
socket.on('send-file', function(name, buffer) {
var fs = require('fs');
//path to store uploaded files (NOTE: presumed you have created the folders)
var fileName = __dirname + '/tmp/uploads/' + name;
fs.open(fileName, 'a', 0755, function(err, fd) {
if (err) throw err;
fs.write(fd, buffer, null, 'Binary', function(err, written, buff) {
fs.close(fd, function() {
console.log('File saved successful!');
});
})
});
});
});
Second step (in my case I've used jade rather html)
extends layout
block content
h1 Tiny Uploader
p Save an Image to the Server
input#input-files(type='file', name='files[]', data-url='/upload', multiple)
button#send-file(onclick='javascript:sendFile();') Send
script(src='http://127.0.0.1:8000/socket.io/socket.io.js')
script(src='/javascripts/uploader.js')
Third and Fourth steps (coding uploader.js to send the file to server)
//variable declaration
var filesUpload = null;
var file = null;
var socket = io.connect('http://localhost:8000');
var send = false;
if (window.File && window.FileReader && window.FileList) {
//HTML5 File API ready
init();
} else {
//browser has no support for HTML5 File API
//send a error message or something like that
//TODO
}
/**
* Initialize the listeners and send the file if have.
*/
function init() {
filesUpload = document.getElementById('input-files');
filesUpload.addEventListener('change', fileHandler, false);
}
/**
* Handle the file change event to send it content.
* #param e
*/
function fileHandler(e) {
var files = e.target.files || e.dataTransfer.files;
if (files) {
//send only the first one
file = files[0];
}
}
function sendFile() {
if (file) {
//read the file content and prepare to send it
var reader = new FileReader();
reader.onload = function(e) {
console.log('Sending file...');
//get all content
var buffer = e.target.result;
//send the content via socket
socket.emit('send-file', file.name, buffer);
};
reader.readAsBinaryString(file);
}
}
Some important considerations:
This is a tiny sample of socket file uploader. I don't consider some important things here: file chunks to send piece of files instead of all content in a row; Update the status of file sent as (error msg, successful msg, progress bar or percent stage, etc.). So this is a sample to initial steps to coding your own file uploader. In this case, we don't need a form to send files, its is completely asynchronous transaction via socket.io.
I hope this post is helpful.
This tutorial goes a little bit further because you can pause/resume your upload but you will find how to upload a file through socketio :)