socket.io emit all clients not emitting over SSL - socket.io

I have the normal socket.io set up:
Client:
import io from 'socket.io-client'
const socket = io()
socket.on('connect', () => {
console.log('connected')
socket.emit('message', 'I have connected')
})
socket.on('message', (msg) => console.log(msg))
Server:
import socket from 'socket.io'
const io = socket(/* httpsServer */)
io.on('connection', (socket) => {
console.log('new connection')
socket.on('message', (msg) => console.log(msg))
socket.emit('message', 'This works!')
io.sockets.emit('message', `This doesn't!`)
})
For some reason emit to all works perfectly via http but not https. Via https the io.sockets.emit doesn't seem to work. Am I missing something?

Check the same socket server module isn't mounted to both httpServer and httpsServer.
I wrapped my socket server in a module and attached it first to the https server and then to the http server. This is why the single sockets would connect but then emit to all was trying to send out to the http sockets only.

Related

Getting "connect_error due to xhr poll error" while connecting socket server

I am trying to connect socket.io client which inside react app to the socket.io server but i am getting xhr poll error. I am unable to figure out what is going wrong? client & server code is as follow:
import io from 'socket.io-client';
const socket = io("ws://loacalhost:5000");
socket.on("connect_error", (err) => {
console.log(`connect_error due to ${err.message}`);
});
const express = require('express');
const app = express();
app.use(require('cors')());
const http = require('http');
const server = http.createServer(app);
const io = require("socket.io")(server, {
rejectUnauthorized: false,
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"]
}
})
io.on("connection", (socket) => {
console.log(socket.id)
})
server.listen(5000, () => {
console.log('Server is listening on Port 5000');
});
Everything is ok in server file as well as everything is ok in client file except there is syntax mistake in client code i.e.
const socket = io("ws://loacalhost:5000");
replaced with:
const socket = io("ws://localhost:5000");
then it is worked fine, successfully connected to server
Your localhost spelling is incorrect.
const socket = io("ws://loacalhost:5000");
Replaced with
const socket = io("ws://localhost:5000");

Can't emit from server to client and from client to server [Socket.io]

I'm creating my product and stuck with this problem. One day I setuped socket.io and everything worked well. On the next day I migrate my server and client from http to https. After the migration client side and server side still connected, but I can't emit from client side to server and from server to client.
Server side
I have my ssl certificate inside ./security/cert.key and ./security/cert.pem they are loading correctly. My server running on https://localhost:5000
import fs from "fs";
import https from "https";
import socketio from "socket.io";
import express from "express";
// HTTPS optiosn
const httpsOptions = {
key: fs.readFileSync("./security/cert.key"),
cert: fs.readFileSync("./security/cert.pem"),
};
// Setup express and https server
const app = express();
const server = https.createServer(httpsOptions, app);
// Setup socket io
const io = socketio.listen(server, {
origins: "https://localhost:3000",
transports: ["websocket"],
});
server.listen(5000, () => {
console.log(`server listening on https://localhost:5000`);
});
io.listen(server);
io.on("connection", (socket) => {
console.log("new socket connected!");
console.log(`data = ${socket.handshake.query.data}`);
socket.emit("some-event");
socket.on("some-event-2", () => console.log("some-event-2 happened!"));
});
Client Side
My example react component. My react app is running on https://localhost:3000. HTTPS is connected and working well.
import React from "react";
import io from "socket.io-client";
const Sandbox: React.FC = () => {
const query = {
"data": 123,
};
const socket = io.connect("https://localhost:5000", {
secure: true,
query,
transports: ["websocket"],
});
socket.on("connect", () => console.log("connect!"));
socket.on("some-event", () => console.log("some event happened"));
socket.emit("some-event-2");
return <React.Fragment />;
};
export default Sandbox;
And now the problem. On client side in console I should see connect! and some event happened
And on server side I should see the messages new socket connected! and data = 123, some-event-2 happened!. But instead my client side console is completely clear
And server side console have only a few logs, but dont contains emit logs
What should I do? Maybe I'm incorrectly using socket.io with https?
I fixed my error.
The problem was that I was firstly create https server and after that only call .listen() on it. listen() - is not a void, it's return another server obj. You need to pass the result of .listen() function inside your io.listen()
// Don't do that❌
var server = https.createServer(options, app);
server.listen(5000);
io.listen(server);
// Do that✅
var server = https.createServer(options, app).listen(5000);
io.listen(server);

Socket IO forbidden 403

I have a simple socket.io app and it works just fine on local and also it's installed successfully on AWS server using plesk admin dashboard but when I connect to the app I always get forbidden {"code":4,"message":"Forbidden"} .. the entry point seems to work great http://messages.entermeme.com .. any idea what could be wrong with it ?
Frontend code
import io from 'socket.io-client'
const socket = io('https://messages.entermeme.com', {
transports: ['polling'],
})
socket.emit('SUBSCRIBE')
Backend code
const cors = require('cors')
const app = require('express')()
const server = require('http').Server(app)
const io = require('socket.io')(server)
server.listen(9000)
app.use(cors())
io.set('transports', [
'polling'
])
io.origins([
'http://localhost:8000',
'https://entermeme.com',
])
io.on('connection', (socket) => {
socket.on('SUBSCRIBE', () => {
//
})
})
had a similar issue but when using nginx. So in case you still need some help:
In the end it turned out to be the URL I specified as socket origins. I didn't specify the port since the origin for me was also running on port 80 (443 for SSL) like in your example above:
io.origins([
'http://localhost:8000',
'https://entermeme.com', // <--- No port specified
])
I updated my config and added the port. So for you it would be:
io.origins([
'http://localhost:8000',
'https://entermeme.com:80', // <--- With port (or 443 for SSL)
])

Sending data received from one socket.io server to a web socket client

I'm starting to use socket.io and I have a problem that I can't solve so far
I have two nodejs running, one is the socket.io data server and the other one is going to interact with web clients
I need to get data from the server and send it to my web clients, the problem is I can't emit data to the clients outside the 'on connect'
I think is better to explain it with a simple example
const socket = require('socket.io-client')('http://localhost:12000');
const SocketIO = require('socket.io');
const app = require('../app');
const server = http.createServer(app);
server.listen(port);
// client socket, this is a regular message from
// the server running on port 12000, it works
socket.on('msg_from_server', data => {
console.log(data);
});
// server socket
const io = SocketIO(server);
io.on('connection', (s) => {
// this works
s.emit('msg_to_client', {data: 'xxxx'})
// this doesn't works
socket.on('msg_from_server', data => {
console.log(data);
});
});
socket client for server on port 12000 and socket from io.on('connection', (socket) both are different. But you are mixing them both.Do something like this:
const Socket_12000 = require('socket.io-client')('http://localhost:12000');
const SocketIO = require('socket.io');
const app = require('../app');
const server = http.createServer(app);
server.listen(port);
// client socket
socket.on('msg_from_server', data => {
console.log(data);
});
// server socket
const io = SocketIO(server);
io.on('connection', (socket) => {
// this works
socket.emit('msg_to_client', {data: 'xxxx'})
// this doesn't works
Socket_12000.on('msg_from_server', data => {
console.log(data);
});
});
I have created a basic gist depicting the problem/solution please commant if you are looking something else.
https://gist.github.com/sandeepp2016/bb1946bcbeb2f11d57bc3aa2e44c158e

Is it possible to use socket.io server with pure html5 websockets?

I want to use sockets in my web app. I don't want to use socket.io library on client-side. It's OK for server-side though. Can I do this?
Now with socket.io on server and pure websocket on client I have destroying non-socket.io upgrade error. I've googled that it means that I have to use socket.io-client library on client-side. Is there any way to avoid that? I don't want client to be tight with this library and use pure html5 websocket instead.
If it's not possible what should I use for server to connect with pure html5 websockets?
If someone is curious here is my server code (coffeescript file)
# Require HTTP module (to start server) and Socket.IO
http = require 'http'
io = require 'socket.io'
# Start the server at port 8080
server = http.createServer (req, res) ->
# Send HTML headers and message
res.writeHead 200, { 'Content-Type': 'text/html' }
res.end "<h1>Hello from server!</h1>"
server.listen 8080
# Create a Socket.IO instance, passing it our server
socket = io.listen server
# Add a connect listener
socket.on 'connection', (client) ->
# Create periodical which ends a message to the client every 5 seconds
interval = setInterval ->
client.send "This is a message from the server! #{new Date().getTime()}"
, 5000
# Success! Now listen to messages to be received
client.on 'message', (event) ->
console.log 'Received message from client!', event
client.on 'disconnect', ->
clearInterval interval
console.log 'Server has disconnected'
And here is a client-side
<script>
// Create a socket instance
socket = new WebSocket('ws://myservername:8080');
// Open the socket
socket.onopen = function (event) {
console.log('Socket opened on client side', event);
// Listen for messages
socket.onmessage = function (event) {
console.log('Client received a message', event);
};
// Listen for socket closes
socket.onclose = function (event) {
console.log('Client notified socket has closed', event);
};
};
</script>
I've found this library, seems OK for my needs https://npmjs.org/package/ws

Resources