I have been fighting with setting this up for longer than I would like to admit.
At first, I was having CORS issues, after following what the socket.io documentation / other stack overflow threads I was getting hit with, GET / POST 400 errors.
Finally after that, I noticed a few threads mention to pass in {transports: ['websocket']} on the server and in the client.
Once I did that, I stopped getting error messages, however, I am still not able to make a connection from my client to my socket.io server. I am hoping I can get some guidance.
I am running Socket.io 3.0 and express 4+
Here is what my server / client looks like at the moment..
SERVER (As an express router)
const express = require('express');
const socketIO = require("socket.io");
const http = require('http');
let app = express();
let router = express.Router();
let server = http.createServer(app);
// The event will be called when a client is connected.
let io = socketIO(server, {transports: ['websocket']})
io.on("connection", socket => {
console.log("connection")
socket.emit("hello", { data: "more data" })
socket.on("disconnect", () => {
console.log("user left")
})
})
server.listen(8081, () => console.log('Socket.io listening on *:8081'));
module.exports = router;
Client (React)
// Socket.IO
import io from 'socket.io-client';
const socket_io = io('localhost:8081', {transports: ['websocket']})
// Socket.io UseEffect
useEffect( () => {
const initSocket = () => {
console.log(socket_io)
socket_io.on("hello", data => {
setSocket(data);
console.log(data);
});
// CLEAN UP THE EFFECT
return () => socket_io.disconnect();
}
initSocket()
},[])
Here is what my Console currently looks like when I log out the socket connection:
So, as embarrassing as this is, the breaking change was that the socket.io-client module in the React client application wasn't 3.0 like the one on the server. Therefore they weren't able to handshake.
My advice, is if you have the CORS rule added or the transport: websocket added, make sure you look at your package.json file in your server / client apps to make sure that the socket.io package version matches.
Related
I am trying to make a simple server with socket.io and express and connect to it through a website.
when i followed a tutorial on socketio with localhost, everything worked fine, but when i put the server on a vserver, and tried to connect to it, i got this error:
Failed to load resource: net::ERR_SSL_PROTOCOL_ERROR
as well as:
GET https://54.53.0.254:47185/socket.io/?EIO=4&transport=polling&t=O09jjrs net::ERR_SSL_PROTOCOL_ERROR
here is my server code:
const express = require('express');
const app = express();
const server = app.listen(47185);
const socket = require('socket.io');
const io = socket(server)
console.log('server running on port 47185');
io.sockets.on('connection', newConnection);
function newConnection(socket) {
console.log('new connection: ' + socket.id);
socket.on('input', inputLog)
function inputLog(data) {
socket.broadcast.emit('input', data);
console.log(data);
}
}
and here is my client code (this is all that relates to socket.io, the rest is just for the website)
var options = {
rejectUnauthorized:false
}
var socket;
socket = io.connect('89.58.0.199:47185', options);
socket.on('input', foreignInput)
function foreignInput(data) {
terminal_animate('\n' + data)
}
i have tried many different fixes and googled everything i can think of, and i'm just not sure what the problem is.
can anyone help me out with this issue? thanks in advance.
In the documentation, according to the Client Initialization part, in node.js you should provide the protocol when connecting to the server.
// the following forms are similar
const socket = io("https://server-domain.com");
const socket = io("wss://server-domain.com");
const socket = io("server-domain.com"); // only in the browser when the page is served over https (will not work in Node.js)
The first two example shows the secure https/wss as protocol, for that you need to serve the required files from the server, example in the documentation.
With http/ws as protocol it should work, but the communication will not be secure.
The Server Initialization / With Express shows an example to call .listen on the return value of createServer from the http module, with the app given as a parameter.
const express = require("express");
const { createServer } = require("http");
const { Server } = require("socket.io");
const app = express();
const httpServer = createServer(app);
const io = new Server(httpServer, { /* options */ });
io.on("connection", (socket) => {
// ...
});
httpServer.listen(3000);
With a caution that says:
Using app.listen(3000) will not work here, as it creates a new HTTP server.
On my debian server, I installed node and then started node server on port 3000. The server is running, but it isn't visible from the browser
Now when I try to get it running via my domain or via my ip(for example xx.xxx.xx.xx:3000) or my domain (my-domain.com:3000) in both cases it doesn't work. I think I don't quite get the concept and I tried to search for a billion different things, but I can't find the solution to my problem. Could someone tell me, if I need to setup something else, too?
My server js code is
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
server.listen(3000, () => {
console.log('listening on *:3000');
});
io.on('connection', function (socket) {
socket.on( 'new_message', function( data ) {
io.sockets.emit( 'new_message', {
message: data.message,
date: data.date,
msgcount: data.msgcount
});
});
});
Error i got
You need to listen for GET requests in order to respond to them.
Try adding something like:
app.get('/', function (req, res) {
res.send('GET request test.')
})
In your case make sure you add the route before passing the app to the http.createServer() method, or otherwise just use something like app.listen(3000).
More info in the docs: https://expressjs.com/en/guide/routing.html
why are you using express and http both packages.
you can run server by either of them.
and then add a get route for it.
import { createServer } from "http";
import { Server } from "socket.io";
const httpServer = createServer();
const io = new Server(httpServer, {
// ...
});
io.on("connection", (socket) => {
// ...
});
httpServer.listen(3000);
I hope this will work!
I have the following (simple) websocket code using socket.io in a node.js-project:
// index.js
const express = require("express");
const app = express();
const http = require("http");
const socketIo = require("socket.io");
const server = http.createServer(app);
const io = socketIo(server);
io.on("connection", (socket) => {
console.log("New client connected");
socket.on("disconnect", () => {
console.log("Client disconnected");
});
});
server.listen(4000, () => console.log('Server running...'));
I'm using a chrome extension to test if I can connect to this server. I'm using Simple Websocket Client.
When I enter the following URL's, I cannot connect to the server:
ws://localhost:4000
ws://127.0.0.1:4000
ws://testserver.loca.lt (localtunnel)
I get an "undefined" error, so it seems there is no error data.
I'm using chrome on macOS. Previously (a few months ago) I was able to create socket.io-servers and connect to them on this machine.
EDIT:
This is the error in the developer console:
websocket.js:88 WebSocket connection to 'ws://localhost:4000/socket.io/?EIO=4&transport=websocket' failed:
There is no error code or error behind 'failed'.
I am trying to connect my quasar application to a socket.io express server hosted on heroku.
The problem is that every time I try to connect, the browser says the request is pending and on the backend I never receive the message of connection.
This is my backend code
const express = require('express');
const app = express();
const PORT = process.env.PORTA || 3000;
const server = app
.use((req, res) => {})
.listen(PORT, () => console.log(`Server is running on port ${PORT}...`));
const io = require('socket.io')(server, {
cors: {
origin: '*',
credentials: true
}
});
io.on('connection', socket => {
console.log('Connected: ' + socket.id);
});
And this is the connection in a boot file in quasar (vue.js) with socket.io extended
import Vue from 'vue'
import VueSocketIOExt from 'vue-socket.io-extended';
import { io } from 'socket.io-client';
const socket = io(URL_CONNECTION);
Vue.use(VueSocketIOExt, socket);
As you can see on the backend I have a console.log to see the id of the connected client. If I try this locally in my pc it works fine and I get the socket id, but on heroku the client doesn't connect without giving me any error.
I found a way to do this. I just removed the custom port I inserted in the server and I put the default (process.env.PORT) and then I connected from the client giving the port 80.
Now, I don't know why, but it's working.
I am using Socket.io in my NodeJS backend. However, the sockets do not work. For example, one should receive a link and then send them to all other rooms under the same code, but the code is not executing. In my heroku logs I receive no errors but when I inspect element the page I get
polling-xhr.js:268 GET https://localhost:5000/socket.io/?EIO=3&transport=polling&t=NDADDNH net::ERR_CONNECTION_REFUSED
and
Failed to load resource: net::ERR_CONNECTION_REFUSED
I have looked into similar problems from this forum and made several changes but none of them have solved the issue. Also a bunch of the posts answer with solutions for ws in general which I don't understand at all :/
From what I read the issue might be with my ports? I followed a few of them but the same errors still occured.
Socket.io:
/***BACKEND***/
const express = require('express');
const path = require('path');
const app = express();
let rooms = [];
/***SERVER***/
const port = process.env.PORT || 5000;
server = app.listen(port, function(){
console.log('App is listening on port ' + port)
});
/***SOCKET.IO***/
const socket = require('socket.io');
io = socket(server);
io.on('connection', (socket) => {
//bunch of functionality
}
and then in my client I am using
this.socket = io('localhost:5000');
//one of the functions
this.syncQueue = () => {
this.socket.emit('SYNC_QUEUE', {
activeRoom: this.props.getRoom()
});
}
this.socket.on('RECEIVE_QUEUE', newQueue => {
props.onAddToQueue(newQueue);
});
FYI Everything works on localhost
Localhost will not work on the server and if you are using default namespace you no need to specify the URL. So try this, this.socket = io()
On the client side, you're trying to connect to localhost:5000 instead of the URL Heroku provides. Try this this.socket = io('heroku url goes here').