I am using twitter streaming api & johnny-five with some other modules http , express& socket.io with arduino uno
My script is working fine in laptop. But my production will be on a tablet. I have two tablets and both are responding differently. On hp omni tablet i am receiving following error
Also i have arduino-uno connected on port COM3 but its shows device connected on COM1
As far as i know this error is caused when standard firmata is not uploded in arduino. I have uploaded this program and it work fine in laptop
On Acer Tablet i am not receiving any errors program starts perfectly fine without any issues but i am not receiving tweets with twitter streaming api
I have crossed checked many times it runs perfectly fine on laptop every time i run it but gives two different issues with the tablets
Here is the code i am using
var Twitter = require('twitter');
var five = require("johnny-five");
var express = require('express')
, app = express()
, http = require('http')
, server = http.createServer(app)
, io = require('socket.io').listen(server);
server.listen(8080);
// routing
app.use(express.static(__dirname + '/http'));
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', "http://"+req.headers.host+':80');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
next();
}
);
var client = new Twitter({
consumer_key: 'abc',
consumer_secret: 'abc',
access_token_key: 'abc',
access_token_secret: 'abc'
});
var board = new five.Board();
board.on("ready", function() {
this.pinMode(5, five.Pin.OUTPUT);
this.pinMode(10, five.Pin.INPUT);
//Ask to visit url
console.log("Visit http://localhost:8080");
var randomHashtag = Math.floor((Math.random() * 10000) +1);
var count = 0;//Initialize counter
io.sockets.on('connection', function (socket) {
console.log('Ready to recieve tweets');//Prints Message when Socket.io is ready to recieve tweets
io.emit('stream',{number:randomHashtag});//Send random no when socket initzilize
client.stream('statuses/filter', {track: '#tweetMe'}, function(stream) {
stream.on('data', function(tweet) {
if(tweet.text.search(randomHashtag) > 0){
count++;//Increment pending tweets
randomHashtag = Math.floor((Math.random() * 10000) +1);
io.emit('stream',{number:randomHashtag});
board.digitalWrite(5,1);
console.log(tweet.text);
}
else{
console.log("Tweet Without random No");
}
});
stream.on('error', function(error) {
throw error;
});
});
});
});
As you said it works perfectly fine with other devices and also managed to fix issue with other tablet the possible reason i can think of is corrupt installation of nodejs or other modules you are using
Try to clean re-installation of Nodejs and all modules. May be there is some problem in your modules not in your code.
Another reason you have following issue nodejs maintain two different version
both handle installing of modules a different way.
Use the same version you are using in your laptop.
I resolved issue with HP OMNI tablet by manually telling johnny-five on which port my arduino is connected as mentioned in OFFICIAL DOCUMENTATION
new five.Board({ port: "COM3" });//FOR WINDOWS ONLY
Also i had to reinstall all modules to make it work
(Still not working with Acer tablet though)
Related
Here is the problem. When I load the page in the browser and check to see if my "test" was emitted, I run into this wall of spamming polling.
The code I use is exactly the same as in other projects I have done, so it makes no sense to me that this doesn't work now. -_-
app.js
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;
server.listen(port, function(){
console.log('server ready - listening on *:8000');
});
app.get( '/*' , function( req, res, next ) {
//This is the current file they have requested
var file = req.params[0];
//Send the requesting client the file.
res.sendFile( __dirname + '/' + file );
});
io.on('connection', function (socket) {
socket.on('test', function(){
console.log("test worked");
});
});
client.js
var socket = io();
socket.emit("test");
I broke the code down to what you see above. There's nothing else. And it doesn't work. internal screaming
I'll post my comment as an answer so you can wrap up this question. One common reason that socket.io will loop with http requests and never successfully connect is if you are running mismatched version on the client and server. This seems to have happened recently with socket.io upon a recent version change so they must have made some change in how the connection logic works that makes it fail to connect if versions are mismatched.
If you load your client via this:
<script src="/socket.io/socket.io.js"></script>
Then, the client will always match the server version as long as you don't have any other <script> tags that are loading some other version of socket.io.
One more solution which worked for me ( Socket.IO 2.3.0 and Socket.IO Client 2.3.0 ) is to set the transports field when you create the instance of io on back-end and socket on front-end , like this :
On back-end :
io = require('socket.io')(http,{
log: false,
agent: false,
origins : '*:*' , // this is for the CORS browser error , I also use the cors npm module here
transports : [ 'websocket' ]
});
And on front-end :
const socket = socketIOClient(url,{
forceNew : false ,
secure : true ,
transports: [ 'websocket' ]
});
Hope it helps , if not the question owner , then maybe the others :)
This is my first post on stackoverflow so pls forgive me if I'm making post taht already existis. I'm kinda new into HTML and .js, "know basics guy".
I have a mobile app on tablet that has kisok mode browser and I'm using it to connect to my NodeJS Server on RPI (works). I have a lot of HTML's and .js files already in my project.
What I'm trying to find out:
Is it possible to make new seperate HTML or .js file that would do something like remote control with my tablet to server. Example - When I click a button taht same button is clicked on browser on RPI beacuse I have another seperate display on RPI that show same thing and I would use my tablet only as a getter of HTML (so I can show it on tablet) and input method for RPI. (simultaneously on both display but use tablet as input)
Or update all existing HTML and .js on server side (harder way, if this thing is even posbile to do)
Thank you very much for further help!
EXtra edit - code
Here is the server side code!
//var app = require('http').createServer(handler);
//var express = require("express")();
var express = require("express");
//var app = require("express")();
var app = express();
var http = require("http").Server(app);
var path = require("path");
//var io = require('socket.io')(app);
var io = require('socket.io')(http);
var SerialPort = require('serialport');
//previous was app.listen(3000);
http.listen(3000);
//Enabling CORS - for specific localhost port
app.use(function (req, res, next){
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8080');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
function handler(req, res){
console.log(req, res);
}
var serialPort = new SerialPort.SerialPort("/dev/ttyAMA0", {
baudrate: 9600,
dataBits: 8,
parity: "none",
stopBits: 1,
flowControl: false
});
var counter = 0;
serialPort.on("open", function () {
console.log("open");
var service = new Service();
serialPort.on("data", function (data) {
var hexData = data.toString('hex');
console.log(data, hexData);
io.emit('hit', data);
});
});
io.on('connection', function(socket){
console.log('Connected');
//nsmrcek - custom code for accepting data from client side
socket.on("message1",function(data){
});
socket.on("message2",function(data){
});
socket.on("message3",function(data){
});
socket.on("message4", function(data){
});
socket.on("message5", function(data){
});
});
app.use(express.static(path.join(__dirname, '/')));
//app.use('/js', express.static(path.join(__dirname,
app.get("/home",function(req,res,next){
//res.send("OK");
//if fails path incorrect
res.sendFile(path.join(__dirname + "/index.html"));
//res.render("index.html");
});
function Service() {
this.mapCodeToHit = function (data) {
"data send from little homemade CPU board via serial port to RPI server" }
I hope this is enough code so You can instruct me where to put more code to simulate click on evry other client while clicking button on one of the clients (alawys 2 clients)
If you created a websocket connection that ran through your server and pushed the updated state of the button to the connected clients this would certainly be possible. I can't give a detailed answer without seeing your code but you could start with the socket.io docs here and ask more questions as you get started.
http://socket.io/
I've got a Node.js app that runs fine locally, but when I push it up to OpenShift it gives me this error in the dev console:
WebSocket connection to 'ws://myapp-mydomain.rhcloud.com/socket.io/?EIO=3&transport=websocket&sid=mpKjro8KjQ5dIg0GAAAE' failed: Error during WebSocket handshake: Unexpected response code: 400
It's a little multiplayer "game", you and any other players connected are cubes that can move around and can see each other's movement etc. I use Node and socket.io to get the player positions and send the new coordinates to other players, but when I host it on OpenShift it gives me the error above.
The weird thing is that it almost works i.e. you can see the other players move around, except it's very laggy and slow.
The same app worked fine on Scalingo hosting, so it must be an OpenShift thing.
This is my client side code for initiating socket.io:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
</script>
And server:
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile('index.html');
});
this.ipaddress = process.env.OPENSHIFT_NODEJS_IP;
this.port = process.env.OPENSHIFT_NODEJS_PORT || 8000;
http.listen( port, ipaddress, function(){
console.log('listening on:' + port);
});
Thank you apsillers, changing this line did the trick:
var socket = io();//OLD
var socket = new io("ws://myapp-mydomain.rhcloud.com:8000/"); //NEW
Still a 90ms delay, but that's an issue for another time. Also a bit annoying that I have to change it back if I want to run and test the app locally (which I do).
I have a simple node.js app with socket.io (1.3.5), taken from socket.io examples:
// Setup basic express server
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var port = process.env.PORT || 3000;
server.listen(port, function () {
console.log('Server listening at port %d', port);
});
// Routing
app.use(express.static(__dirname + '/public'));
io.of('/admin').on('connection', function(socket){
//handle conection on /admin namespace
});
io.of('/user').on('connection', function(socket){
//handle conection on /user namespace
});
Now in my front-end I connect to these specific namespaces like so (again, taken from the example):
var admin_socket = io('/admin');
var user_socket = io('/user');
The app is running on port 3000 and the website is opened using URL localhost:3000.
When doing that I am getting CORS errors, it seems like Socket.io on client side is not auto-detecting the port number as soon as I start using namespaces (in firefox dev tools I can see requests going to localhost/ rather than localhost:3000/).
If on my server-side I don't use namespaces:
io.on('connection', function(socket){
//handle general conection
});
And on front-end I connect this way:
var socket = io();
Everything works fine, port auto-discovery works and in firefox dev tools I can see connections being made to localhost:3000/.
Alternatively, if I still use namespaces on my back-end, and on front end I connect like so:
var admin_socket = io('localhost:3000/admin');
var user_socket = io(':3000/user'); //I can skip localhost
Again everything works (and indeed in firefox dev tools I can see network requests going to localhost:3000/).
How come the port auto-discovery is not working with namespaces? Is there a way to get it to work? Am I missing something here? Thanks.
See my answer below for a fix...
Ok so I did some debugging of code in socket.io.js and realized there is a potential bug there. On line 1050 a loc.hostname is used instead of loc.host.
This causes a hostname to be used when passing in a namespace, this doesn't include port number.
In case of no namespace being used, on line 1024 loc.host is being used and everything is fine.
I have taken a copy of the file and changed line 1050 to use host and everything works fine.
Found github issue with that, it is fixed in 1.4.x:
https://github.com/Automattic/socket.io-client/issues/812
No need to mess with ports, it pretty much should work just by
var admin_socket = io('/admin');
var user_socket = io('/user');
I don't think there is any way to get the auto port discovery to work without modifying the actual Socket.io code or waiting for a fix. The simplest thing you could do is just insert the current location.port including a colon before your namespace.
var admin_socket = io(':' + location.port + '/admin');
var user_socket = io(':' + location.port + '/user');
Or create a new function that will create a socket for you.
function sio(nsp) {
return io(':' + location.port + nsp);
}
How to do socket.io implementation in Webrtc Video calling?
A little bit overload but it works: SocialVidRTC
I understand from your question that you already have a WebRTC project and some signalling mechanism in server.js , possibly websockets .
To replace this with socket.io or any other signalling as SIP / XHR / AJAX etc , you need to replace server.js with new socket.io based code for request and response .
Follow these steps :
create a https server ( since webrtc pages capture web cam input only from secure origins) for socket.io. Assign server to an variable say app.
var fs = require('fs');
var https = require('https');
var options = {
key: fs.readFileSync('ssl_certs/server.key'),
cert: fs.readFileSync('ssl_certs/server.crt'),
ca: fs.readFileSync('ssl_certs/ca.crt'),
requestCert: true,
rejectUnauthorized: false
};
var app = https.createServer(options, function(request, response){
request.addListener('end', function () {
file.serve(request, response);
}).resume();
});
app.listen(8081);
here server.key , server.crt and ca.crt are fake ssl certs and 8081 is the https port I have selected .
you can reuse the same https server for hosting the webpages also.
listen on this same port for socket.io using app defined earlier
var io = require('socket.io').listen(app, {
log: false,
origins: '*:*'
});
io.set('transports', [
'websocket'
]);
I choose only websocket but you can set other types of transport too such as
socket.set('transports', [
'websocket'
, 'flashsocket'
, 'htmlfile'
, 'xhr-polling'
, 'jsonp-polling'
]);
Now implement signalling specific functions and calls such as ,
io.sockets.on('connection', function (socket) {
...
socket.on('webrtc-joinchannel',function(data){
var resp=joinChannel(data);
socket.emit('resp-webrtc-joinchannel', resp);
});
...
});
Note : I am using socket.io v0.9 .
If yo want a example implementation you can view any sample projects such as here