I am using socket.io to create an interactive graph app. on the server side have a graph variable. When the user loads the page a test event is sent to the server, which sets up the variable and returns it to the users. I have a second event for node dragging, but when i try to drag the node the server says that the graph's nodes and link variables are undefined.
var express = require('express'),
app = express(),
http = require('http'),
socketIo = require('socket.io');
var server = http.createServer(app),
io = socketIo.listen(server);
var graph = {nodes : [], links : []}
server.listen(8080, function(){
console.log('server is listening on localhost:8080');
});
app.use(express.static(__dirname + '/'));
io.on('connect', function(socket){
// dump some test data
socket.on('test', function(){
// this just creates a few nodes in an array
var data = { ... }
graph = data;
io.emit('test', graph);
});
socket.on('eventNodeDragStart', function(index){
console.log('event node drag start: ' + index);
// undefiend, the graph.nodes is empty here
console.log(graph.nodes[index] + "\n\n");
// cannot read property of undefined
// also missing error handler on 'socket'
if(graph.nodes[index].locked) return;
graph.nodes[index].locked = true;
io.emit('eventNodeDragStart', index);
});
});
Solved the problem by replacing this line:
io.on('connect', function(socket){
with this:
io.sockets.on('connect', function(socket){
Not sure why it works, but it does.
Related
I have the following example using Node.js for the server that sends data via Socket.io to a Javascript file. All works well locally, but when I uploaded to Heroku, it does not. I have tried a lot of tips I found online, but I am always stuck and can't get it through. At the moment, I don't get errors, but I also can't see the values coming through.
Here is the code I use at the moment:
var express = require('express');
var socket = require('socket.io');
//store the express functions to var app
var app = express();
//Create a server on localhost:3000
var server = app.listen(process.env.PORT || 3000);
//var server = app.listen((process.env.PORT || 3000, function(){
//console.log("Express server listening on port %d in %s mode", this.address().port, app.settings.env);
//});
//host content as static on public
app.use(express.static('public'));
console.log("Node is running on port 3000...");
//assign the server to the socket
var io = socket(server);
//dealing with server events / connection
io.sockets.on('connection', newConnection); //callback
//function that serves the new connection
function newConnection(socket){
console.log('New connection: ' + socket.id);
socket.on('incomingDataToServer', emitFunction);
function emitFunction(data){
//setInterval(() => socket.broadcast.emit('ServerToClient', new Date().toTimeString()), 1000);
let randNum;
setInterval(function(){
//get a random value, and assign it a new variable
randNum = getRandomInt(0, 100);
}, 1000);
socket.broadcast.emit('ServerToClient', randNum);
//following line refers to sending data to all
//io.sockets.emit('mouse', data);
console.log(randNum);
}
}
And the Javascript here:
let socket;
socket = io();
socket.on('ServerToClient', socketEvents);
function socketEvents(data){
incomingData = data;
console.log(data);
}
Any help is appreciated.
Thanks
Write app.use before the app listen
and modify app.listen as below and check heroku logs for console message.
app.use(express.static('public'));
var server = app.listen(port, function() {
console.log('Server running on ' + port + '.');
});
if It still not work let me know.
I have a few questions about configuring socket.io for my node.js application.
When requiring var socket = require('socket.io')( /* HERE */ ), do I need to input the port my server listens where the /* HERE */ is at?
Right below the above line, I have another require function, for a .js file that contains a few constants and a function (see below). When I try to refer to 'socket' in that file it says it's undefined. But since this line is below the require line for the socket.io middleware seen above, why does it say 'undefined'?
const numbers = '1234'
function asd(req,res,next) {
socket.emit('a')
}
module.exports = {
asd
}
For configuring client-side socket.io, I added this line:
var socket = io.connect('https://mydomain')
Do I need to say 'mydomain:port' or is 'mydomain' enough?
This is how you use socket.io
var http = require('http');
var express = require('express');
var path = require('path');
var app = http.createServer();
var io = require('socket.io')(app);
var port = 8081;
io.on('connection', function(socket){
socket.on('event1', function (data) {
console.log(data);
socket.emit('event2', { msg: 'delivered' });
});
});
app.listen(port);
Answer to your second question
Yes, you will need to specify the port you are using
<script src="socket.io.js"></script>
<script>
var socket = new io.Socket();
socket.connect('https://mydomain:8081')
socket.on('your_event',function() {
console.log('your_event receivid from the server');
});
</script>
Here socket will connect to port 8081
This is a simple server side code
var http = require('http');
var io = require('socket.io');
var port = 8081;
// Start the server at port 8081
var server = http.createServer();
server.listen(port);
var socket = io.listen(server);
// example listener
socket.on('event_2', function(client){
console.log('event_2 received');
});
// example emitter
socket.emit('event_1', { hello: 'world' });
I have a simple setup where I have some draggable divs and I want to use sockets.io to update the position between clients.
On my client (index.html) I have :
// find the elements
var elements = document.getElementsByClassName('ball'),
labelsX = document.getElementsByClassName('coords-x'),
labelsY = document.getElementsByClassName('coords-y');
// loop over the 3 items...
for (var n = elements.length; n--;) {
// ... augment our default options with individual `onDrag` handlers
var opts = {
onDrag: onDragFactory(n),
setCursor: true
};
// ... and initialize drag for each
window.d = new Draggable(elements[n], opts);
console.log('ddd');
}
// bind `n` to its value at iteration time
function onDragFactory (n) {
return function (element, x, y) {
//This doesnt seem to work
console.log(elements[n].style.top);
socket.emit('positionx', elements[n].style.top);
socket.on('positionx', function(positionx){
elements[n].style.top= positionx.value();
});
}
}
My server is then :
var express = require('express');
var path = require('path');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var publicPath = path.resolve(__dirname, 'public');
app.use(express.static(publicPath));
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
//Server Side Listen for an event from the client
io.on('connection', function(socket){
socket.on('positionx', function(positionx){
console.log('recieving');
console.log(positionx);
io.emit('positionx', positionx);
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
The server however doesn't seem to receive any information. Is there something I'm doing wrong? Any help would be much appreciated!
In your client you need to define socket.
var socket = io();
Also, make sure you are including socket.io-x.x.x.js prior to calling socket.io in your javaScript. You are probably already doing this, but it's unclear without seeing more code.
I have this code working for receiving data from my Arduino but I will like to send data back to my Arduino and get a response on my client page. I added a listening function but I keep getting io.on is not a function when I send data from my client page.
test.js
io.listen(app.listen(3000)).on('connection', function (client) {
// store client into array
clients.push(client);
// on disconnect
client.on('disconnect', function() {
// remove client from array
clients.splice(clients.indexOf(client), 1);
});
// I added this to listen for event from my chart.JS
io.on('connection', function(socket){
socket.on('LED on', function (data) {
console.log(data);
});
socket.on('LED off', function (data) {
console.log(data);
});
});
});
Your value of io is not what it should be.
The usual way of doing things is like this:
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');
app.listen(80);
io.on('connect', ...);
But I'm guessing that your value of io is something like this:
var io = require('socket.io');
That's not the same thing. That's the module handle. But, when you do it this way:
var io = require('socket.io')(app);
Then, io is a socket.io instance. You can bind listeners to an instance, not to the module handle.
In every single socket.io server-side example on this doc page, they use one of these forms:
var io = require('socket.io')(app);
var io = require('socket.io')(port);
var io = require('socket.io')(server);
with this:
io.on('connection', ....);
Nowhere do they do:
var io = require('socket.io`);
io.listen(server);
io.on('connection', ....);
That's just the wrong value for io.
Long story, shortened, you need to fix what you assign to io to be consistent with the docs. It's the return value from require('socket.io')(app); that gives you a socket.io instance object that you can then set up event handlers on.
if you are using express
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
let APP_PORT=3000;
server.listen(APP_PORT,()=>{
console.log(`SERVER RUNNING ON PORT : ${APP_PORT}`);
});
io.on('connection', (socket) => {
/* SOCKET - CORE EVENTS */
socket.on('connect', (message) => {
console.log("connected: " + message+"socket_id:"+socket.id);
});
socket.on('disconnect',(data)=>{
console.log('user disconnected:' + socket.id);
});
socket.on('error', function (err){
console.log('received error from client:', socket.id,' Error :',err);
});
});
I am having troubles with app.io.emit('admin', 'balls'); inside of the games.js file. The emits inside of the io.on('connection' output in the browser.
/bin/www
var app = require('../server'); //Which has references to games.js
app.set('port', process.env.PORT || 4001);
var server = app.listen(app.get('port'));
var io = require('socket.io')(server);
io.on('connection', function (socket) {
socket.emit('admin', { hello: 'received' });
socket.on('admin', function (data) {
console.log(data);
});
});
app.io = io;
/app/controllers/admin/games.js
// inside server.js -> require('games.js')(app);
module.exports = function(app) {
//.....Other stuff
app.io.emit('admin', 'balls');
});
Html
script(src="/js/socket.io-1.3.5.js")
script.
$(function () {
var socket = io();
socket.on('admin', function (data) {
console.info(data);
});
})
console output on page load in Chrome
WebSocket connection to 'ws://localhost:4000/socket.io/?IO=3&transport=websocket&sid=QxjoI-yYF54oaQieAAAB' failed: Connection closed before receiving a handshake response
games:8 Object {hello: "received"}
I would like to be able to do emits whenever I want. Why isn't this working? Is it because I have to declare a reference to io with app.io and I am not starting the server with ('http')?
It turns out to be something in my particular build that I over looked. The code was correct in how I was going about it.
I have gulp which I am then using broswerSync to proxy my instance so it can auto reload once everything has compliled.
My server is using port 4001 but the proxied site uses 4000 so when I navigated to 4001 everything was working as expected. No JS errors