This is my first project with these technologies and English is not my native language forgive me for all mistakes.
I am making Real-time Arduino NodeJS MongoDB project. My main goal is getting humidity, temperature and gas values from arduino. Storing them in Mongodb and publish these values on web site (localhost for now). Here is my NodeJS file. Couple variables are Turkish but its not that important i assume.
// Express bir server kurduk
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var port = process.env.PORT || 8000;
// 8000. Porttan bağlantıyı sağlıyoruz
// mongoose kullandığımız veri tabanı kısmımız
var mongoose = require('mongoose');
var promise = mongoose.connect('mongodb://localhost/deneme2', {
useMongoClient: true,
});
promise.then(function(db) {
console.log('database e baglanildi')
});
// mongoose şeması tanımlaması
var Schema = mongoose.Schema;
var Veri = new Schema({
nem: String,
sicaklik: String,
sicaklik2: String,
sicaklik3: String,
gas: String,
body: String,
date: { type: Date,default: Date.now }});
var Veriler = mongoose.model('veri', Veri);
// server dinleniyor fonksiyonu
server.listen(port, function () {
console.log('Server listening at port %d', port);
});
// yönlendirme
app.use(express.static(__dirname + '/public'));
var SerialPort = require("serialport").SerialPort
var serialPort = new SerialPort("/dev/ttyACM0", { //Arduino bağlantısını sağladığımız USB portumuz
autoOpen: false,
parser: SerialPort.parsers.readline('\r\n'),
baudrate:115200 // bitrate'imiz
});
//serialporttan okuyan ve datayı ekranımıza yazan fonksiyon
serialPort.open(function () {
console.log('NodeJS Arduino Projemiz Hazır');
serialPort.on('data', function(data) {
console.log(data);
io.sockets.emit('message', data.toString());
var test=data.toString();
var temp=test.split(",");
var veritabani=new Veriler({
nem: temp[0],
sicaklik: temp[1],
sicaklik2: temp[2],
sicaklik3: temp[3],
gas: temp[4]
});
veritabani.save(function(err){
if(err) throw err
});
});
});
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function (socket) {
});
Everything is fine. I am getting my data from Arduino like this way 31.0,24.0,297.0,185
I am saving it to the database but this is the first object which is wrong
{
"_id" : ObjectId("5a5285dd36e0c007967c3f66"),
"nem" : "",
"date" : ISODate("2018-01-07T20:41:01.168Z"),
"__v" : 0
}
And this is the second object which is correct.
{
"_id" : ObjectId("5a5285dd36e0c007967c3f67"),
"nem" : "32.0",
"sicaklik" : "24.0",
"sicaklik2" : "297.0",
"sicaklik3" : "56.0",
"gas" : "228",
"date" : ISODate("2018-01-07T20:41:01.193Z"),
"__v" : 0
}
It goes on and on againg like this one correct one wrong. I am using 800ms delay but i am going to try to change delay. I have no idea what is the problem. Also my html file :
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Ev Otomasyonu</title>
<script src="/socket.io/socket.io.js"></script>
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script>
var socket = io.connect('http://localhost');
socket.on('message',function(data){
test=data.toString();
temp=test.split(',');
$('#nem').temp[0];
$('#sicaklik').text(temp[1]);
$('#sicaklik2').text(temp[2]);
$('#sicaklik3').text(temp[3]);
$('#gas').text(temp[4]);
});
</script>
</head>
<body>
<div>
<h1>Nem</h1>
<h1 id='nem'></h1>
</div>
<div>
<h1>Celcius</h1>
<h1 id='sicaklik'></h1>
</div>
<div>
<h1>Fahrenheit</h1>
<h1 id='sicaklik2'></h1>
</div>
<div>
<h1>Kelvin</h1>
<h1 id='sicaklik3'></h1>
</div>
<div>
<h1>Gaz</h1>
<h1 id='gas'></h1>
</div>
</body>
</html>
Which does not give me my values just writing the headers. I assume its because the first object in database that saved before.
According to the sample code in serialport package, you are listening with the 'flowing mode' which can introduce such behaviour. Have you try using the non flowing mode?
see sample code:
// Switches the port into "flowing mode"
port.on('data', function (data) {
console.log('Data:', data);
});
// Read data that is available but keep the stream from entering "flowing mode"
port.on('readable', function () {
console.log('Data:', port.read());
});
Related
Hope you are doing well,
As I am creating a multiplayer games, so i need to store all user details from socket, after some time I need to make a group from the Users list.
So I tried to implement https://github.com/socketio/socket.io-redis library and trying to get all connected users but it's not working, I have developed according to this example Example to use socket.io-redis, but it'not work for me and my redis server is working well.
Thanks
Example :
index.js
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));
var your_namespace_socket = io.of('/');
app.get('/', function(req, res) {
res.sendfile('index.html');
});
your_namespace_socket.on('connection', function(socket) {
console.log(socket.id);
socket.on('join', function(room) {
socket.join(room);
console.log(room);
//log other socket.io-id's in the room
your_namespace_socket.adapter.clients([room], (err, clients) => {
console.log(clients);
});
});
});
server.listen(3000, function() {
console.log('listening on *:3000');
});
index.html
<html>
<head>
<title>Hello world</title>
</head>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('/');
socket.emit('join', 'testingroom');
</script>
<body></body>
</html>
Output
User has joined session in a room with cannot fetch data from redis, as you can see in screenshot
Output of Above Code
I tested your code and it works for me, it might be an error with redis, do you have any error in the callback :
your_namespace_socket.adapter.clients([room], (err, clients) => {
if(err) console.log(err)
console.log(clients);
});
I found a coding from tutorials point to run a a simple socket.io chat server in localhost, I installed necessary environments like nodejs, express, init package.json and I started the server from terminal using command-"node app.js", then I accessed the index page in my localhost it showed the chat page, it is working fine. But the thing is I want to use this is in a live server for my office, to chat within the office. Is this code is enough for that. I am new to this socket.io and nodejs. My office has live server for hosting their website, this code opens and listens to port 3000. It will be highly helpful if you could tell me how to run this in a real server.
Index.html
<!DOCTYPE html>
<html>
<head>
<title>Hello world</title>
</head>
<script src = "/socket.io/socket.io.js"></script>
<script>
var socket = io();
function setUsername() {
socket.emit('setUsername', document.getElementById('name').value);
};
var user;
socket.on('userExists', function(data) {
document.getElementById('error-container').innerHTML = data;
});
socket.on('userSet', function(data) {
user = data.username;
document.body.innerHTML = '<input type = "text" id = "message">\
<button type = "button" name = "button" onclick = "sendMessage()">Send</button>\
<div id = "message-container"></div>';
});
function sendMessage() {
var msg = document.getElementById('message').value;
if(msg) {
socket.emit('msg', {message: msg, user: user});
}
}
socket.on('newmsg', function(data) {
if(user) {
document.getElementById('message-container').innerHTML += '<div><b>' +
data.user + '</b>: ' + data.message + '</div>'
}
})
</script>
<body>
<div id = "error-container"></div>
<input id = "name" type = "text" name = "name" value = ""
placeholder = "Enter your name!">
<button type = "button" name = "button" onclick = "setUsername()">
Let me chat!
</button>
</body>
</html>
app.js Server
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res) {
res.sendfile('index.html');
});
users = [];
io.on('connection', function(socket) {
console.log('A user connected');
socket.on('setUsername', function(data) {
console.log(data);
if(users.indexOf(data) > -1) {
socket.emit('userExists', data + ' username is taken! Try some
} else {
users.push(data);
socket.emit('userSet', {username: data});
}
});
socket.on('msg', function(data) {
//Send message to everyone
io.sockets.emit('newmsg', data);
})
});
http.listen(3000, function() {
console.log('listening on localhost:3000');
});
You can solve your problem through nginix( A reverse proxy server). Nginx have .conf file which contains the server realted configuration.
server { listen 3000; server_name io.yourhost.com; }
To run:
Sudo service nginx start
It will start your server on given IP or Domain name.
Change the declaration variable socket by
var socket = io(Server IP + ':port');
Example:
var socket = io('127.0.0.1:3000);
I using socket.io version 2.0.2
I'm developing a server app in Node.js. For better understanding I wrote a very light code just to better point my issue. This is the server-side:
Server.js
var express = require('express');
var app = express();
var port = process.env.PORT || 80;
var room = function(){
this.users = {};
this.counter = 0;
}
app.get('/reg',function(req,res){
console.log(req.params);
});
app.use('/recosh', express.static(__dirname + '/public/'));
app.listen(port, function(){console.log('ReCoSh Server Starts...\n');});
So inside the "public" directory I wrote the two following client-side files:
room.js
var room = {
//notifica al server una nuova registrazione
register: function(data){
$.getJSON('/reg',data);
}
}
index.html
<!doctype html>
<html>
<head>
<script src="room.js"></script>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script>
var register = function() {
room.register({
"username": $("#username").val(),
});
}
</script>
</head>
<body>
<div id="step1">
<input id="username">
<button onclick="register()">register</button>
</div>
</body>
</html>
The problem is that by inserting an username and clicking on register, the code console.log(req.params); on the server just print {}. It seems the object is empty... If I try console.log(req.params["username"]) it prints undefined.
Why this simple object is not visible by the server?
First of all you should change a little typo in your code into this
room.prototype.addUser = function(username){
if(username){
this.users[username] = username;
this.counter++;
}
}
changing this.user[username] to this.users[username]
Then change app.use('/register'.. to app.get('/register'.., but I would recommend to use post method, but let's make work with little modifications and besides this you don't call the register function inside the callback. So you should do something like this:
app.get('/register',function(req,res){
var data = {
username: req.params['username']
}
room.addUser(data.username);
console.log('user added\n');
});
On the other hand in your client side the input id is equal to nickname whereas you get the value by username id, so you should make this change as well:
<input id="nickname"> to <input id="username">
I'm currently making a small nodejs app to monitor the player count on a game server. Here is my app.js
var express = require('express');
var http = require('http');
var query = require('game-server-query');
var app = express();
var server = http.createServer(app);
var io = require('socket.io')(server);
function ping(callback) {
query({
type: 'arma3',
host: 'xx.xxx.xxx.xxx'
},
function(state) {
var num = state.raw.numplayers;
callback(num);
}
);
}
app.get('/', function(req, res) {
ping(function(num) {
res.render('index.ejs', {
count: num
});
});
});
io.on('connection', function(socket) {
socket.on('_pask', function () {
ping(function(num) {
socket.emit('_prefresh', num);
});
});
});
server.listen(8080);
and here is my client file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Data</title>
</head>
<body>
<p>Players:
<%= count %>
</p>
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
socket.on('_prefresh', function(num) {
console.log(num);
});
setInterval(function() {
socket.emit('_pask');
}, 3000);
</script>
</body>
</html>
so basically, sometimes, the request takes more than a second so the app crashes with "Cannot read property 'numplayers' of undefined", I assume it means that the program tries to read the integer and that it cannot read it because the query isn't finished yet.
So, can anyone of you help me please ?
It means that state is coming as undefined from backend for some reason, add a check for state.
function ping(callback) {
query({
type: 'arma3',
host: 'xx.xxx.xxx.xxx'
},
function(state) {
if(state !== undefined){
var num = state.raw.numplayers;
callback(num);
}
}
);
}
On your server code, only do the emit IF the value is set.
Fire the emit every second using settimeout
setTimeout(function() {
if (value!=null) {
socket.emit HERE
} else {
console.log("not emitting coz value not set");
}
}, 1000);
I know this question is kind of awkward, but the problem comes from Samsung TV 2010 / 2011 SmartTV (and blue ray player; of course 2012 emulator working fine). I ported the simple chatting examples come from the source and package to SmartTV app. Both of them fall back to JSONP polling, but from SmartTV app only could emit / push to server once. Receiving the message from server could be multiple times without any problem. After looking for the answer in Samsung D forum (of course nothing there), I think the fastest way to work around this issue is to deploy an Express server, taking the post data and JSON.parse, then emit Socket.io / Sockjs internally inside the server itself.
Could anybody show me an easy sample code so I could start from there? Thanks a lot.
I quickly make code, but seems it doesn't work:
lib/server.js
var express = require('express')
, app = express.createServer()
, io = require('socket.io').listen(app);
app.listen(80);
app.use(express.bodyParser());
app.get('/', function (req, res) {
res.sendfile('/var/www/mpgs_lite_v3/index.html');
});
app.post('/', function(req, res){
console.log(req.body);
io.sockets.emit('my other event', req.body);
res.redirect('back');
});
io.sockets.on('connection', function (socket) {
//socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
index.html
<html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
</head>
<body>
<form method="post" action="/">
<input type="hidden" name="_method" value="put" />
<input type="text" name="user[name]" />
<input type="text" name="user[email]" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
'my other event' seems not receive anything.
UPDATE: I updated the example for you to make it more complete. I didn't have an app.listen before, and here is also a client side script which shows that it, indeed, works fine:
<!doctype html>
<html>
<head>
<script src="//www.google.com/jsapi"></script>
<script src="/socket.io/socket.io.js"></script>
<script>google.load("jquery", "1.7.1")</script>
<script>
var socket = io.connect("localhost", {port: 3000});
socket.on("foo", function(message) { console.log("foo: ", message) });
$(function() {
$("button").click(function() {
$.post("/foo", { message: $("input").val() });
});
});
</script>
</head>
<body>
<input type=text>A message</input>
<button>Click me!</button>
</body>
</html>
And the server, now with an app.listen directive:
var express = require("express"),
app = express.createServer(),
io = require("socket.io").listen(app)
index = require("fs").readFileSync(__dirname + "/index.html", "utf8");
app.use(express.bodyParser());
app.get("/", function(req, res, next) {
res.send(index);
});
app.post("/foo", function(req, res, next) {
io.sockets.emit("foo", req.body);
res.send({});
});
app.listen(3000);
Usage:
node app.js
Navigate to http://localhost:3000/ and click the button. Check your console for output.
Based on SockJS express example server.js could look like:
var express = require('express');
var sockjs = require('sockjs');
// 1. Echo sockjs server
var sockjs_opts = {sockjs_url: "http://cdn.sockjs.org/sockjs-0.2.min.js"};
var sockjs_echo = sockjs.createServer(sockjs_opts);
connections = {};
sockjs_echo.on('connection', function(conn) {
console.log(conn.id);
connections[conn.id] = conn
conn.on('close', function() {
delete connections[conn.id];
});
// Echo.
conn.on('data', function(message) {
conn.write(message);
});
});
// 2. Express server
var app = express.createServer();
sockjs_echo.installHandlers(app, {prefix:'/echo'});
console.log(' [*] Listening on 0.0.0.0:9999' );
app.listen(9999, '0.0.0.0');
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
app.post("/send", function(req, res, next) {
for(var id in connections) {
connections[id].write('received POST');
}
res.send({});
});
To test open browser at localhost:9999 and run:
curl localhost:9999/send -X POST
just remove this comment
//socket.emit('news', { hello: 'world' });
to
socket.emit('news', { hello: 'world' });
it will work because its emiting data through news and you are listening using my other event instead of 'news' or you can do just listen using 'my other event'
I don't know if this would help, but you can make an emit abstraction on the client based on your browser and then make a separate get function on the server that will handle the request the same way as the socket.on callback. In order to know where to send the information I suggest you use some key that you can store in a hash table in the server and local storage on the client.
For the client:
var emit = function(event, options) {
if ("WebSocket" in window) {
socket.emit(event, options);
console.log("emited via WebSocket");
} else {
$.post("http://localhost/emit/" + event, options);
console.log("emited via AJAX");
}
}
emit("echo", {
key: localStorage.getItem("key"),
data: {
hello: "world"
}
});
socket.on("response", function(data) {
console.log(data.hello); //will print "world"
});
For the server:
var sockets = {};
var echo_handler = function(a) {
var socket = sockets[a.key];
var data = a.data;
socket.emit("response", data);
}
app.post("/emit/:event", function(req, res) {
var event = req.params.event;
switch (event) {
case "echo":
var a = {
key: req.param("key"),
data: req.param("data")
}
echo_handler(a);
break;
}
});
io.sockets.on("connection", function(socket) {
socket.on("connect", function(data) {
sockets[data.key] = socket;
});
socket.on("echo", echo_handler);
});
Another way to do this will be to switch to Sockjs and use their patch.
If someone have better solution for Socket.IO it will be appreciated, because I'm already deep into the project and it's too late to switch Socket.IO for Sockjs, and this solution is not to my liking :( .