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'.
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.
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'm working on chat app, I have Android version made in Flutter, where Socket.IO works fine. Now I'm making web app of this chat app. But when the app tries to connect to server, the error is thrown:
WebSocket connection to 'ws://localhost:3000/socket.io/?EIO=4&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 400
Here is client code (I'm using React):
console.log("Connecting to websocket...");
this.socket = io(this.serverUrl(), {
transports: ["websocket"],
autoConnect: false
});
this.socket.on("connection", (data) => {
console.log("Connected webscoket.");
this.socket.emit("join", { token: this.token });
});
this.socket.connect();
Here is server code (Node.js), (The code is not complete, of course):
const express = require("express");
const app = express();
const http = require("http").createServer(app);
const port = process.env.PORT;
const io = require("socket.io")(http);
http.listen(port, () => {
console.info("Server is running on port " + port);
});
io.on("connection", async (socket) => {
console.log("Connected socket.io client " + socket.id);
});
socket.on("disconnect", async (reason) => {
console.log("Socket disconnected");
});
I also tried to add origins like this:
const io = require("socket.io")(http, {
origins: ["http://localhost:3001"]
});
Then the error is not there, but it never connects, and server console output looks like this:
Server is running on port 3000
Connected to database
Connected socket.io client QkoLREixPEyNglK7AAAA
Connected socket.io client QkoLREixPEyNglK7AAAA
Socket disconnected
Connected socket.io client C-j2N_Bvz8QDEQKUAAAB
Connected socket.io client C-j2N_Bvz8QDEQKUAAAB
Socket disconnected
Connected socket.io client 4Q6vxnNJb0gR-rVtAAAC
Connected socket.io client 4Q6vxnNJb0gR-rVtAAAC
Socket disconnected
Connected socket.io client g7MMXfwBuqjtS31_AAAD
Connected socket.io client g7MMXfwBuqjtS31_AAAD
Socket disconnected
Connected socket.io client NIquCegqW9yygXkIAAAE
Connected socket.io client NIquCegqW9yygXkIAAAE
...
Also the Android app stop working this way.
Thank you for all your answers.
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.
I have seen this question several times, but I feel that my use case is not quite addressed, so I'm posting it below:
I get this error when trying to connect to my websocket:
scripts.js:44 WebSocket connection to 'ws://localhost:3000/' failed: Error during WebSocket handshake: Unexpected response code: 200
There's one small change that makes it fail versus succeed. See below:
Server.js:
'use strict';
const express = require('express');
const WebSocket = require('ws');
const PORT = process.env.PORT || 3000;
// Failing:
const server = express().use(express.static('public'));
server.get('/', function (req, res) {
res.sendFile(path.join(__dirname + '/public/index.html'));
});
server.listen(PORT, () => {
console.log(`Example app listening on PORT ${PORT}!`)
});
///
// Working (no websocket connection issues):
///const server = express().use(express.static('public'))
// .listen(PORT, () => {
// console.log(`Example app listening on PORT ${PORT}!`)
// });
const wss = new WebSocket.Server({ server });
wss.on('connection', function connection(ws) {
console.log(ws);
ws.on('message', function incoming(message) {
console.log('received message: %s', message);
wss.clients.forEach(function each(client) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(message);
}
});
});
});
relevant: client code:
var HOST = location.origin.replace(/^http/, 'ws');
var socket = new WebSocket(HOST); //this is the line where the connection is attempted.
Running on localhost, ngrok, or deployed to heroku seems to make no difference, unless I missed something...
I have tried various things from other posts but to no avail. They mention changing networking configurations (doesn't seem relevant to my use), or various ways to configuring express js, but they don't help. It's really just that small change in the above code. Is the websocket hitting the GET route?