I found this error using socket.io latest version: "index.js: 83 POST http: //localhost/socket.io/? EIO = 3 & transport = polling & t = MDUHEO9 404 (Not Found)".
I understand the reason: the true address must be http: // localhost: 3000 / socket.io /.
Do you know how I can correct?
I have read many discussions, but no one has a suitable solution for version 2.1.0, even in a discussion I read a downgrade proposal, I would like to avoid it.
client.js:
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
var socket = io().connect('http://localhost:3000');
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
});
</script>
server.js:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
});
Change this:
var socket = io().connect('http://localhost:3000');
to this:
var socket = io.connect('http://localhost:3000');
or to this:
var socket = io('http://localhost:3000')
Either of these last two are the same.
You will want to use only one form of connect, either io(...) or io.connect(...), not both. When you call just io() you're trying to connect to the default URL which will be the URL of the current web page and then when you then try to also do .connect() after that, you're trying to connect again. You only want one connection and to the specified URL.
The problem here is that you've defined any endpoint to server socket.io client file. That's why you are getting 404.
If you've installed in with npm, you can allow express to server that kind of static files for you by just adding the following line
app.use(express.static(__dirname + '/node_modules'));
if you've installed socket.io with bower, use
app.use(express.static(__dirname + '/node_modules'));
Or you can place that socket.io's client library at any location and server the file against the requests like
app.get('/socket.io', function(req, res){
res.sendFile("Path to socket.io.js file");
});
And you don't need to write full address in
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
Just use
<script src="/socket.io/socket.io.js"></script>
Related
I have a platform running with Apache + PHP which I distribute to several people through subdomains, Ex: platform.subdomain1.com, platform.subdomain2.com,etc..
. And I would like one of the features of this platform to be Video streaming and i chose to do this with Node.js + socket.io. I don't have much Node experience but I managed to make streaming itself work. I basically have a directory called stream with app.js, index.html and two html files: one to stream the video and one to view.
My problem:
I would like to merge the two so that I can link to these streaming and viewing pages so that each user with their subdomain has their own streaming.
I wonder if there is any way to do it and what it would be.
I could create a directory with the all node streaming files inside each subdomain and create a new instance for each one, like this:
var app = new express();
const http = require("http").Server(app)
http.listen('platform.subdomain1.com',3000);
So that I could link my platform to the address: platform.subdomain1.com/stream:3000
but I'm not sure if it is right to do this or if there is another way to do it. If anyone can help me thank you very much!
My App.js
var express = require("express");
var app = new express();
const http = require("http").Server(app)
var io = require("socket.io")(http);
app.use(express.static(__dirname + "/public"));
app.get('/', function(req,res){
res.redirect('index.html');
});
io.on('connection', function(socket){
socket.on('stream', function(image){
socket.broadcast.emit('stream', image);
});
});
http.listen(3000);
yes, this is the right way to work with socket.io and express together
create express server
bind express server to socket.io
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(80);
// WARNING: app.listen(80) will NOT work here!
app.get('/ping', function (req, res) {
res.send("pong")
});
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Advantage with express:
You will have support for ping/pong or health check in case of AWS load balancer health check or any platform that route request base on target health as socket.io does not support health check in AWS ALB.
you check official documentation suggested by socket.io.
socket.io-Using-with-Express
I'm more or less following the socket.io documentation and trying to apply it to my slightly different project but I believe I'm making some mistake. I've used express-generator to create my project's skeleton and therefore I got app.js file, www file and route files.
I've put this code in www file:
var io = require('socket.io')(http);
console.log('Socket is running!');
io.on('connection', function(socket){
console.log('A User Has Connected: ' + socket.id);
});
This code in my footer file:
<script src="/socket.io/socket.io.js"></script>
<script src="/javascripts/jquery-3.2.1.min.js"></script>
<script src="/javascripts/javascript.js"></script>
</body>
</html>
And this in my JavaScript file:
$(document).ready(function(){
var socket = io();
});
Now I understand that when a request is made, the console should log "A User Has Connected: " + the id of the socket but I'm not getting anything other than "Socket is running!". I assume I'm missing something but can't figure it out and the documentation is using the same code.
var port = normalizePort(process.env.PORT || '8087');
app.set('port', port);
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
You have to use the same server instance express-generator creates, which is the following line in www file
var server = http.createServer(app);
To use that, change
var io = require('socket.io')(http);
to
var io = require('socket.io')(server);
I am trying to use in socket.io in my node.js app, but my client can't get the library from my sever and I don't know why.
Error: Failed to load resource: the server responded with a http://localhost:3000/socket.io/socket.io.js status of 404 (Not Found)
Server site:
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.use(express.static('public'));
app.get('/', function (req, res) {
res.sendFile( __dirname + "/" + "index.html" );
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
io.on('connection', function(socket){
console.log('a user connected');
});
Client side:
<head>
<link rel="stylesheet" href="/stylesheets/style.css" />
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
</script>
</head>
Your index.html code couldn't find socket.io because you are sendig only Index.html for response. Please try following code.
Use following code:
//"client" is folder for client code which contains index.html
app.use(express.static(__dirname + '/client'));
Remove following code. Node.js will find index.html automatically.
app.get('/', function (req, res) {
res.sendFile( __dirname + "/" + "index.html" );
});
Change your index.html
New code:
<script src="https://cdn.socket.io/socket.io-1.3.7.js"></script>
Old code:
<script src="/socket.io/socket.io.js"></script>
I don't know exactly why your code isn't working, but if socket.io is installed properly, then it automatically configures a route in Express to serve the request for /socket.io/socket.io.js. So, apparently socket.io is not configured/installed properly in your situation.
I can tell you that this initialization of Express and socket.io works and does not have the problem you speak of:
var express = require('express');
var app = express();
var server = app.listen(80);
var io = require('socket.io')(server);
I had the same problem in my index.html while learning Node.js.
The console prompted similar error
I removed socket.io module by executing npm r socket.io in my project directory and re-installed it using npm i socket.io and then it worked fine.
I just began with node.js a few days ago and I'm know trying to use socket.io module. But it is not working as I was expecting. The example I am trying to reproduce is this one :
http://robdodson.me/blog/2012/06/04/deploying-your-first-node-dot-js-and-socket-dot-io-app-to-heroku/
I know that the version of Express they are using is outdated so I updated my code to fit with the new versions of the modules they are using.
The problem I have is that my client doesn't get what my server is emitting, here is my server-side code :
var express = require('express'),
http = require('http'),
app = express(),
port = 8080, // Use 8079 for dev mode
server = http.createServer(app).listen(process.env.PORT || port, function(){
console.log('Express server listening on port %d in %s mode', server.address().port, app.settings.env);
}),
io = require('socket.io').listen(server),
routes = require('./routes');
// Configuration
app.configure(function() {
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function() {
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function() {
app.use(express.errorHandler());
});
// Heroku won't actually allow us to use WebSockets
// so we have to setup polling instead.
// https://devcenter.heroku.com/articles/using-socket-io-with-node-js-on-heroku
io.configure(function () {
io.set("transports", ["xhr-polling"]);
io.set("polling duration", 10);
});
// Routes
app.get('/', routes.index);
var status = "All is well.";
io.sockets.on('connection', function (socket) {
io.sockets.emit('status', { status: status }); // note the use of io.sockets to emit but socket.on to listen
socket.on('reset', function (data) {
status = "War is imminent!";
io.sockets.emit('status', { status: status });
});
});
And here is client-side :
<script src="http://localhost:8080/socket.io/socket.io.js">
var socket = io.connect(document.location.href);
</script>
<div id="status"></div>
<button id="reset">Reset!</button>
So if I understood well, what I should get is "All is well" on the first time in the status div, and "War is imminent !" if I click reset.
But all I get is nothing.
I tried those answers but I can't see any differences between the solution code and mine, or sometimes it's just outdated :
1. Node.js + socket.io: app on server not working correctly
2. NodeJS - Socket.IO Setup: served static content no handshake (Ubuntu on Rackspace Cloud Server)
I tried all of the solutions that were given in the other subjects but it definitely won't work for me.
Every modules are correctly installed. I followed the steps given in the tutorial I followed at first.
If anyone has any idea of what is going on or if anyone experienced the same issue you are welcome.
Thanks.
The reason your client isn't doing anything is because you aren't telling it to do anything. You need to assign handlers for it to do something. So, to fix this, you'd need to tell the reset button to use socket.emit() when being clicked, and you'd also need to assign a handler for the status event in order to change the contents of the div.
<script type="text/javascript" src="http://localhost:8080/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io.connect(document.location.href);
</script>
<div id="status"></div>
<button id="reset" onclick="socket.emit('reset')">Reset!</button>
<script type="text/javascript">
socket.on('status', function(data) {
document.getElementById('status').innerHTML = data.status;
});
</script>
I've been following the tutorial at https://www.tutorialspoint.com/socket.io/, and I have the following 2 files:
app.js:
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', {root: __dirname});
});
io.on('connection', function(socket) {
console.log('A user connected');
//Send a message after a timeout of 4 seconds
setTimeout(function() {
socket.send('Sent a message 4 seconds after connection!');
}, 4000);
socket.on('disconnect', function () {
console.log('A user disconnected');
});
});
http.listen(80, function() {
console.log('listening on *:80');
});
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Hello world</title>
</head>
<script src = "/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('message', function(data){document.write(data)});
</script>
<body>Hello world</body>
</html>
If I run this in Node.js version 10.16.3 and visit http://localhost/, everything works fine. The server console logs:
A user connected
And the browser eventually displays:
Sent a message 4 seconds after connection!
So far, so good!
The problems arise when I try to run this from my website. Let's pretend it's called example.com.
My web hosting provider uses the same version of Node.js, and has set it up so that each Node.js application runs in a subfolder. Let's pretend it's called example.com/x.
When visiting http://example.com/x, the browser displays:
Cannot GET /x/
So in app.js, I changed this:
app.get('/', function(req, res) {
res.sendFile('index.html', {root: __dirname});
});
...to this:
app.get('/x', function(req, res) {
// Redirect if no slash at the end
if (!req.url.endsWith('/')) {
res.redirect(301, req.url + '/')
}
res.sendFile('index.html', {root: __dirname});
});
Now the initial page loads, but the browser console logs:
The resource from “http://example.com/socket.io/socket.io.js” was blocked due to MIME type (“text/html”) mismatch (X-Content-Type-Options: nosniff).
Loading failed for the <script> with source “http://example.com/socket.io/socket.io.js”.
ReferenceError: io is not defined
Obviously, my app doesn't get a chance to handle this request because it's addressed to the main domain.
So I changed both files:
In app.js, I changed this line:
var io = require('socket.io')(http);
to this:
var io = require('socket.io')(http, {path: "/x/socket.io"});
And in index.html, I changed this line:
<script src = "/socket.io/socket.io.js"></script>
to this:
<script src = "/x/socket.io/socket.io.js"></script>
This got rid of the errors in the browser console, but it still doesn't seem to be connecting.
The browser never displays:
Sent a message 4 seconds after connection!
Same when I run all this in http://localhost/x/, and the Node.js console never logs:
A user connected
Is there an easier way to go about all this than the changes I've been making so far?
If not, what more do I need to do to get this working?
One step left.
In index.html, change this line:
var socket = io();
...to this:
var socket = io.connect("/", {path: "/x/socket.io"});
This should work for both http://example.com/x and http://localhost/x.