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
Related
I have implemented a user interface to do some wizard of oz testing. I have a user-side page (Page A), and a second page, the wizard page (Page B). They use the same data and page B receives some information from page A to load the correct data. When the user asks questions on page A, the question is sent to page B, and an answer should be sent back to page A. The problem is that Page A is open on device A and page B is open on Device B (both are on the same server).
I am trying to implement the communication between page A and page B using socketIO. I searched for hours and didn't find a complete example of connecting two apps using socketIO. They usually open the same app in multiple windows. That won't help me. My understanding so far is that I should create a server for each app, and then have the two servers communicate with each other. What I have so far doesn't work and no communication is happening. What I have is as follow:
for page A (index.html):
I added a index.js server file:
// Import packages
const express = require("express");
const socketIO = require("socket.io");
const path = require("path");
// Configuration
const PORT = process.env.PORT || 3000;
//const INDEX = path.join(__dirname, 'index.html');
const INDEX = path.join(__dirname, 'index.html');
console.log("INDEX", INDEX);
//const WIZARD = path.join(__dirname, 'wizard.html');
// Start server
const server = express()
//.use((req, res) => res.sendFile(INDEX), (req, res) => res.sendFile(WIZARD))
.use((req, res) => res.sendFile(INDEX))
.listen(PORT, () => console.log("Listening on localhost:" + PORT));
// Initiatlize SocketIO
const io = socketIO(server);
var other_server = require("socket.io-client")('http://localhost:4000');
other_server.on("connect",function(){
other_server.on('message',function(data){
// We received a message from Server 2
// We are going to forward/broadcast that message to the "Lobby" room
io.to('lobby').emit('message',data);
});
});
io.sockets.on("connection",function(socket){
// Display a connected message
console.log("User-Client Connected!");
// Lets force this connection into the lobby room.
socket.join('lobby');
// Some roster/user management logic to track them
// This would be upto you to add :)
// When we receive a message...
socket.on("message",function(data){
// We need to just forward this message to our other guy
// We are literally just forwarding the whole data packet
other_server.emit("message",data);
});
socket.on("disconnect",function(data){
// We need to notify Server 2 that the client has disconnected
other_server.emit("message","UD,"+socket.id);
// Other logic you may or may not want
// Your other disconnect code here
});
});
For the same app, to the index.html I added the following script:
<script type="text/javascript">
// Get WebSocket
var socket = io.connect('http://localhost:3000');
// Client
socket.on('connect', function(){
socket.emit("message","This is my message");
socket.on('message',function(data){
console.log("We got a message: ",data);
});
});
// Join a channel
var room = "test";
socket.emit("join", room);
let msg = "hello helloo helloooo from index.html";
socket.emit("new_message", msg);
socket.on("new_message", function (msg) {
console.log("sending a message through server from index.html", msg);
});
</script>
For the second app, wizard.html I added a server file, index.js:
// Import packages
const express = require("express");
const socketIO = require("socket.io");
const path = require("path");
// Configuration
const PORT = process.env.PORT || 4000;
//const INDEX = path.join(__dirname, 'index.html');
const INDEX = path.join(__dirname, 'wizard.html');
console.log("INDEX", INDEX);
//const WIZARD = path.join(__dirname, 'wizard.html');
// Start server
const server = express()
//.use((req, res) => res.sendFile(INDEX), (req, res) => res.sendFile(WIZARD))
.use((req, res) => res.sendFile(INDEX))
.listen(PORT, () => console.log("Listening on localhost:" + PORT));
// Server 2
const io = socketIO(server);
io.sockets.on("connection",function(socket){
// Display a connected message
console.log("Server-Client Connected!");
// When we receive a message...
socket.on("message",function(data){
// We got a message. I don't know, what we should do with this
});
});
and to the wizard.html, I added the script below:
<script type="text/javascript">
// Get WebSocket
//var socket = io();
var socket = io.connect('http://localhost:4000');
// Join a channel
var room = "test";
socket.emit("join", room);
let msg = "hello helloo helloooo from wizard";
socket.emit("new_message", msg);
socket.on("new_message", function (msg) {
console.log("sending message through server from wizard", msg);
});
/*
*/
</script>
I also added <script src="/socket.io/socket.io.js"></script> to both apps, index.html, and wizard.html.
In wizard.html I get this error:
POST http://localhost:4000/socket.io/?EIO=3&transport=polling&t=OAp7bZr 400 (Bad Request)
and in index.html I get this error:
Access to XMLHttpRequest at 'http://localhost/socket.io/?EIO=3&transport=polling&t=OAp7k5w' from origin 'http://localhost:3000' has been blocked by CORS policy:
If you can help me figure out what I am missing or if you know of any complete working example similar to what I am trying to accomplish, I would very much appreciate it if you let me know.
It would be even more helpful if someone could use the code and scenario I provided here and write a minimum working example in which the two apps, a.html, and b.html, can communicate through socketIO.
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.
Background: I have a node.js server running on my localhost (call this Server A); and an external server running node.js at https://example.net:3000 (call this Server B). I do not control or have access to Server B (it is a dashboard site for an IoT device in my home), but I need to connect to is using socket.io and emit a specific message.
I can connect to it easily from a flat javascript file (client-side), but need it running server side (ultimate goal is to make it into something I can call with an HTTP request); and examples such as How to connect two node.js servers with websockets? suggest I should be able to use socket.io-client from node.js with nearly the same code to achieve the same results. But when I run the code from node.js, I cannot connect to the socket.
Below is the code that works successfully in flat javascript file. I know it works because I see 'socket connect' in the console, and I can also test for the the socket emit at the end.
var myemail = "email#gmail.com";
var device_id = '12345';
// Create SocketIO instance, connect
var socket = io.connect('https://example.net:3000');
socket.on('connect', function(){
try {
console.log('socket connect');
socket.emit('configure', {email:myemail, deviceid:device_id});
} catch(e) {
console.log(e);
}
});
socket.emit("/" + device_id, "45678");
...and below is the code I cannot get to work when running from my node.js instance. I'd expect a message 'socket connect' in the command line log and get nothing.
var express=require('express');
var http=require('http');
var app=express();
var server = http.createServer(app);
//Variables
var myemail = "email#gmail.com";
var device_id = '12345';
var io = require('socket.io-client');
var socket = io.connect('https://example.net:3000');
//Connect listener
socket.on('connect', function(){
try {
console.log('socket connect');
socket.emit('configure', {email:myemail, deviceid:device_id});
} catch(e) {
console.log(e);
}
});
socket.emit("/" + device_id, "45678");
Any ideas?
UPDATE
Ran debug utility, results included as linked image below. Key thing I see is that engine.io tries to do an xhr poll, and gets a 503 response back from the server. (Obviously not a true 'temporary error' with the server as again, this all works from running client-side js in chrome).
debugging output image link
Solved this - issue was that the server I was connecting to required use of https, so I needed to add
{secure: true, rejectUnauthorized: false}
after the url to connect to.
Full working example:
const myemail = email#email.com;
const device_id = 12345;
io = require('socket.io-client');
var socket = io.connect('https://server.net:3000',{secure: true, rejectUnauthorized: false});
function doStuff(){
//Listener
socket.on('connect', function(){
try {
console.log('socket connect');
socket.emit('configure', {email:myemail, deviceid:device_id});
} catch(e) {
console.log(e);
}
});
socket.emit("/" + device_id, "003021");
}
doStuff();
I think the line causing the issue is :
var socket = io.connect('https://example.net:3000');
I managed to make a working example using this code :
const myemail = "email#gmail.com";
const device_id = '12345';
var socket = require('socket.io-client')('https://example.net:3000');
socket.on('connect', function(){
try{
console.log('socket connect');
socket.emit('configure', {email:myemail, deviceid:device_id});
}catch(e){ console.log(e); }
});
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);
});
});
Bases
I'm trying to use sockets on my node project. This is the how it basically works :
/
|-> controllers/
| |-> home.js
|-> app.js
|-> sockets.js
/app.js
On app, I call sockets.js to start the socket server :
var express = require('express');
var sockets = require('./sockets');
var app = module.exports = express();
var server = app.listen(config.PORT);
var io = sockets(server);
/sockets.js
On this file I start the socket server, and return io.
var socket = require('socket.io');
module.exports = function(server) {
var io = socket.listen(server);
io.sockets.on('connection', function(socket) {
// Here I can call every socket I want (if I have the socket_id) with this code :
var socket = io.to(socket_id);
socket.emit('message', {});
});
return io;
};
Question
But now, I want to retrieve my io server on my home controller and call a specific socket. I've tried to do this :
/controller/home.js
var io = require('../sockets.js');
module.exports = {
home: function(req, res, next) {
var socket = io.to(socket_id);
socket.emit('message', {});
}
};
But I have this error, cause I don't execute the function (but I don't want create a new socket server here) :
TypeError: Object function (server) {
var io = socket.listen(server);
/*.....*/
return io;
} has no method 'to'
I want to get an access to the io variable returned by this function called on app.js. How Can i get it ?
You could convert sockets.js into an object that exposes your io property. You would also add a function listen that app.js calls during initialization.
// sockets.js
module.exports = {
listen: function(server) {
this.io = socket.listen(server);
//...
return this.io;
}
}
Your controller can then access require('../sockets.js').io, You just need to make sure io is defined at the time you use it, or otherwise make sure app.js calls listen before your controller gets invoked.
You must be convert sockets.js into an object that exposes your io property.
You would also add a function listen that app.js calls during initialization.
Your controller can then access require('../sockets.js').io.