I am getting started with node.js/express/socket.io and am having issues making the whole thing work. Not sure it is important but I am using an Express4 TypeScript project from Visual Studio 2022.
Apologies in advance for the long question but I spent a long time doing investigations and sharing what I found out so far may very well save you some time.
The symptoms are:
- Chrome + MS Edge: I have the below 3 error messages (although only the first 2 are about socket.io)
- Firefox : Only the uncaught ReferenceError is there.
In all 3 browsers, http://localhost:3000/socket.io/socket.io.js shows the scripts successfully. The error/warning mention retrieving that file through port 1337 though.
That leads me to 2 questions:
- How come the Chromium-based browsers report they are unable to find the socket.io script file whereas Firefox does not?
- What can I do to make the errors disappear.
I suppose, maybe incorrectly, that the uncaught ReferenceError is related to that line in the webpage:var socket = io();
Notes:
Because of the starting sentence of Handling CORS ("Since Socket.IO v3, you need to explicitly enable Cross-Origin Resource Sharing (CORS)."), I checked the change log page and figured my attempt with socket.io years ago, from which the below code was copied, was on socket.io v2. That would explain why it used to work, but no more does (additionally, the listening channel was on var port = process.env.PORT || 3000;
, which now makes node.js crash completely with EADDRINUSE: address already in use
).
I visited many questions on SO, socket.io and elsewhere, to no avail. I did not check when browsing but I assume most are not applicable to socket.io v3 and later.
Here is my code (developed under Visual studio):
index.ts
import express = require('express');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var port = 3000;
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function (socket) {
console.log('New user connected');
socket.on('disconnection', function () {
console.log('User disconnected');
});
socket.on('chat message', function (msg) {
io.emit('chat message', msg);
});
});
http.listen(port, function () {
console.log('listening on *:' + port);
});
const router = express.Router();
router.get('/', (req: express.Request, res: express.Response) => {
res.render('index', { title: 'Express' });
});
export default router;
index.html
(generated from a .pug
file)
<!DOCTYPE html>
<html>
<head>
<title>Express</title>
<link rel="stylesheet" href="/stylesheets/main.css">
</head>
<body>
<ul id="messages"></ul>
<form id="form" action="">
<input id="input" autocomplete="off">
<button>Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io() ;
var form = document.getElementById('form');
var input = document.getElementById('input');
form.addEventListener('submit', function(e) {
e.preventDefault();
if (input.value) {
socket.emit('chat message', input.value);
input.value = '';
}
});
</script>
</body>
</html>
Edit: What I am really after is astandalone solution.
4 years and 2 major version later, the socket.io website suggests this is still possible, see:
-
Handling CORS
That page starts with the following sentence:Note: this also applies to localhost if your web application and your server are not served from the same port
const io = new Server(httpServer, { cors: { origin: "http://localhost:8080" } }); httpServer.listen(3000);
-
AFAICT, the client code (here) could not be more straightforward and appears to match my code too.
<script src="/socket.io/socket.io.js"></script> <script> const socket = io(); </script>
I could not find a mention of a weird trick to put things together. Yet,
I tried to modify my server code as above (with cors: { origin: http://localhost:8080"}
and cors: { origin: "http://localhost:1337" }
since the latter is the port my http server listen to), I still get error 404.
2
Answers
The main problem is the browser unable to load the
socket.io
library.Replace :
with
as recommended in https://socket.io/get-started/chat#integrating-socketio or implement a way to get the local file in your node server.
error 404 indicated that the browser is unable to find the socket.io.js file.
Socket.io server exposes its clientside js file, try using that.
here is your client.
regarding CORS, you should implement CORS and for production maybe you want to implement further security then use the helmet(or ignore the helmet and remove it)
in the server pay attention to a commented line
for testing only (not for production), you can simply ignore everything and enable this to avoid all CORS and security.