invalid JSON in message - node.js

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");
});

Related

How to Emit data from function using Socket io

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

automatically pair up peer to peer connections using socket.io, socket.io-p2p, socket.io-p2p-server

I am attempting to hook up a small game with WebSockets. I am using socket.io, socket.io-p2p, and socket.io-p2p-server. I want users to be automatically paired up against any connected player who doesn't have a partner. I want users to only be connected in pairs.
So far simply following the docs I can only get clients to connect using just socket.io. When I attempt to use socket.io-p2p and socket.io-p2p-server I can sometimes get users to connect and other times I get error messages on the screen like
"Missing error handler on socket.
TypeError: Cannot read property 'emit' of undefined"
Someone opened an issue for this problem on the repo and didn't get a response and never got a response
https://github.com/tomcartwrightuk/socket.io-p2p-server/issues/5
I don't know if socket.io-p2p-server is broken or if I am just missing something. Further more socket.io-p2p-server has not been touched much since march.
So my main questions are:
Is socket.io-p2p-server still alive?
Is there a better implementation I can use for these abstractions?
Would writing my own logic instead of using socket.io-p2p-server be worth it?
client side code
import P2P from 'socket.io-p2p'
import io from 'socket.io-client'
const socket = io()
const p2pSocket = new P2P(socket, null, function () {
console.log("my id is: " + p2pSocket.peerId)
})
p2pSocket.on('peer-msg', function (data) {
console.log(data)
})
server side code
var http = require('http')
var httpServer = http.createServer(requestHandler)
var fs = require('fs')
var io = require('socket.io')(httpServer)
var p2pServerModule = require('socket.io-p2p-server')
var p2p = p2pServerModule.Server
var connectedUsers = p2pServerModule.clients
io.use(p2p)
httpServer.listen(8000, 'localhost');
function serveUpFile(req, res, path) {
fs.readFile(path.toString(), function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200)
res.end(data)
})
}
function requestHandler (req, res) {
if (req.url === '/static/bundle.js') {
serveUpFile(req, res, './static/bundle.js')
} else {
serveUpFile(req, res, './index.html')
}
}
io.on('connection', function (client) {
console.log('client connected to the server')
client.on('peer-msg', function (data) {
console.log('Message from peer %s', data)
})
client.on('disconnect', function () {
console.log('client disconnected from the server')
})
})
socket.io-p2p-server will not work with socket.io 1.x as expected.
Change socket.io-p2p-server/index.js:
This part:
if (typeof room === 'object') {
var connectedClients = socket.adapter.rooms[room.name]
} else {
var connectedClients = clients
}
To this:
if (typeof room === 'object' && ('name' in room) && (room.name in socket.adapter.rooms) ) {
var connectedClients = {}
for (var id in socket.adapter.rooms[room.name].sockets) {
connectedClients[id] = clients[id];
}
} else {
var connectedClients = clients;
}
This solution works for me.

Node client receiving too many hit from node server on single update

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

Faye PubSub Extension adding extra data field in messages

I am using Faye with Node.js (javascript) for a chat server and I am trying to implement 'notices' so that when one use subscribes, the server will send a message to the channel with a property __messageType = 'subscribe'
The server code looks like so (the ext field is present and working just fine)
var chat = new Faye.NodeAdapter()... //etc
chat.addExtension({
incoming: function(message, callback) {
if (message.channel === '/meta/subscribe') {
console.log('A new user subscribed');
chat.getClient().publish(message.subscription, {
ext: message.ext,
__messageType: 'subscription'});
}
callback(message);
}
});
On my client side I have attached an 'incoming' extension so that people can easily determine if this is a subscription notification and not an actual 'data message'
clientChat.addExtension({
incoming: function(message, callback) {
console.log('Incoming message', message);
message.getType = function() {
return message.__messageType;
};
messge.getData = function(key) {
return message.ext[key];
};
callback(message);
}
});
I am structuring my messages this way that way people can do something like this:
var sub = new Faye.Client(url).subscribe('/messages', function(message) {
if (message.getType() === 'subscribe') console.log('Someone subscribed');
if (message.getType() === 'unsubscribe') console.log('Someone left');
else console.log('Ext data: ', message.ext);
The problem is that my messages are coming through with the ext field wrapped in a 'data' field and I have no idea where it's coming from. My getType and getData methods have been successfully added, but they obviously don't work because the ext field is no longer present at the top level, they are instead embedded in the message's data field.
Expected: Actual:
channel: "/messages" channel: "/messages/"
ext: { variousData } data: {ext: variousData}
getData: function (key) { getData: function(key) {
getType: function () { getType: function() {
id: "4" id: "4"
Does anyone have any idea why I'm getting that 'data' field in my messages?

Send data when opening a socket in node.js

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.

Resources