Cannot connect to socket.io connection in node.js - node.js

I'm new to node.js and, having worked through the relevant parts of the Wexler book, I am trying to create a simple stream using socket.io.
Here is my node.js server code:
const port = 3000,
dataIntervalMillis = 5000,
express = require("express"),
app = express(),
crypto = require('crypto');
const server = app
// .get("/", (req, res) => {
// res.send("Run this project by typing in <b>nodemon</b> in the node.js command prompt.");
// })
.listen(port, () => {
console.log(`RNG Server running on port number ${port}`);
}),
io = require("socket.io")(server);
io.on("connection", client => {
console.log("RNG client connected.");
io.emit("New RNG client connection.");
client.on("disconnect", () => {
console.log("RNG client disconnected.");
io.emit("RNG client disconnected.");
});
});
I have built a standalone Java application to test the stream:
//import java.io.BufferedReader;
import java.io.InputStream;
//import java.io.InputStreamReader;
//import java.io.PrintStream;
import java.net.Socket;
public class SimpleSocketClientExample {
public static void main(String[] args) {
String server = "localhost";
int port = 3000;
try {
// Connect to the server
System.out.println("Connect to server " + server + " on port " + port + "...");
Socket socket = new Socket( server, port );
System.out.println("...connected.");
//BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );
InputStream in = socket.getInputStream();
System.out.println("Reading byte...");
int b = in.read();
System.out.println("...byte read.");
// Close our streams
if (in != null) {
in.close();
}
if (socket != null) {
socket.close();
}
}
catch( Exception e ) {
e.printStackTrace();
}
}
}
The problem is that this client code hangs on the in.read() line.
The only console log from the server is RNG Server running on port number 3000. There is no RNG client connected in the server log, which indicates that the client has not connected (or has connected to something else).
I've tested my node.js app using online socket testers, and they don't seem to connect either - indicating the problem probably lays with my node.js server app.
Can anyone advise what I may have missed?

Turns out socket.io doesn't create a standard TCP socket.
My solution was to leave my client code untouched and change the Node.js server code to use the net library instead.
In case it might help anyone else that runs into the same issue, here's my new code:
const port = 3000;
const { createServer } = require('net');
const server = createServer();
// A counter to facilitate assigning of socket.id.
let counter = 0;
// An array of connected client sockets that we will broadcast to.
let sockets = {};
server.on('connection', (socket) => {
socket.id = counter++;
console.log(`A client has connected: ${socket.id}`);
// Catch errors so they don't stop the application.
socket.on('error', function () {
console.log(`Client error: ${socket.id}`);
delete sockets[socket.id];
});
// Set character encoding.
socket.setEncoding('utf8');
// Add socket to array.
sockets[socket.id] = socket;
// When connection ends, remove socket from array.
socket.on('end', data => {
console.log(`${socket.id} has disconnected`)
delete sockets[socket.id];
});
});
server.listen(port, () => {
console.log(`RNG Server running on port number ${port}`);
});

Related

NodeJS & WebSocket learn ip and port of client

Suppose that i have two of applications which is written below:
server.js
const express = require('express');
const app = express();
const WebSocketServer = require('ws');
var http = require('http');
let server = http.createServer(app).listen(8000);
const wss = new WebSocketServer.Server({ server: server })
// Creating connection using websocket
wss.on("connection", (ws, req) => {
console.log("req.socket.localPort = ", req.socket.localPort);
console.log("req.socket.remotePort = ", req.socket.remotePort);
console.log("req.socket.remoteAddress = ", req.socket.remoteAddress);
console.log("new client connected");
// sending message
ws.on("message", data => {
console.log(`Client has sent us: ${data}`)
});
// handling what to do when clients disconnects from server
ws.on("close", () => {
console.log("the client has connected");
});
// handling client connection error
ws.onerror = function () {
console.log("Some Error occurred")
}
});
and i have a "client" with same code base (code example) which listens port 8001.
Undoubtly, client's open address is 'ws://localhost:8001' and server's 'ws://localhost:8000'. When i make request to server from client,
console.log("req.socket.remotePort = ", req.socket.remotePort);
prints different ports after each message sending. But i want to get the number of 8001. How i can get the number of client's actual port of 8001?

Flutter Socket io disconnects after some seconds

Am using a local socket server using express which is expose to the internet using ngrok. This is the server code:
const app = require('express')();
const http = require('http').createServer(app);
app.get('/', (req, res) => {
res.send("Node Server is running. Yay!!");
});
//Socket Logic
const socketio = require('socket.io')(http)
socketio.on("connection", (userSocket) => {
console.log('Connected to socket');
});
http.listen(3000, () => {
console.log('listening on port 3000');
});
and my connection logic is:
void connectToServer() {
try {
socket = io('https://fa6387728fcd.ngrok.io', <String, dynamic>{
'transports': ['websocket'],
'autoConnect': false,
});
// Connect to websocket
socket.connect();
// Handle socket events
socket.on('connect', (data) => print('Connected to socket server'));
socket.on('disconnect', (reason) => print('disconnected $reason'));
socket.on('error', (err) => print('Error: $err'));
} catch (e) {
print(e.toString());
}
}
But i keep getting disconnected ping timeout or sometimes i get disconnected transport close
I had the same problem.
The problem wasn't caused by the socket_io_client package.
When i update socket.io on my server side, the problem is solved.
Just run npm install socket.io#latest command on your node.js server.
According to the socket_io_client official doc, use this workaround if you are using https server:
class MyHttpOverrides extends HttpOverrides {
#override
HttpClient createHttpClient(SecurityContext context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
void main() {
HttpOverrides.global = new MyHttpOverrides();
runApp(MaterialApp(
...
));
}

Using Socker.io, emitting does nothing just after connecting

I just started using socket.io for my Node.js server. My problem is that I cannot emit anything immediately after connecting.
Nothing happens. No errors. But no emitting !
This is server:
const app = express();
const server = app.listen(3000);
const io = socket(server);
io.on("connect", (socket: Socket) => {
console.log("Client connected...");
// This does nothing
socket.emit("Sending immediately", 'sent!');
setTimeout(() => {
socket.emit("Sending with delay", 'delayed');
}, 1000);
}
And the client code is this:
(I'm checking the received messages in Firefox Network tab)
export class Server {
private io: SocketIOClient.Socket;
constructor() {
this.io = io('127.0.0.1:3000');
}
...
}

socket.io failing after refresh page in client side

I am using socket.io in a react - node project. I have a problem with the socket not refreshing when the page refreshes.
It works first as the server and the react dev server run for the first time. After using the socket ( emitting something from the server ), refreshing the browser page would result in an error in the web socket.js file :
WebSocket connection to
'ws://localhost:4000/socket.io/?EIO=3&transport=websocket&sid=XTE63CeWdp676cRXAAAF'
failed: Error during WebSocket handshake: Unexpected response code:
400
here is the code I use in client and server :
SERVER :
const express = require('express');
const socketconfig = require('./socket.io');
class Server {
constructor({ config, router, logger, }) {
this.config = config;
this.logger = logger;
this.express = express();
this.express.disable('x-powered-by');
this.express.use(router);
}
start() {
return new Promise((resolve) => {
const http = this.express
.listen(this.config.web.port, () => {
const { port } = http.address();
this.logger.info(`[p ${process.pid}] Listening at port ${port}`);
resolve();
});
var io = require('socket.io').listen(http,function () {
console.log("I AM CONNECTIONG")
});
this.freshio=io.sockets;
socketconfig.setOnConnection(this.freshio, ()=>{
console.log('Connexion COnditions are set');
});
socketconfig.setOnDisconnect(this.freshio, ()=>{
console.log('client disconnected');
});
this.clients = socketconfig.clients;
});
}
}
module.exports = Server;
the start() method would be called when the server is initiated.
the socketConfig file is just a toolkit for saving clients and setting conditions, it doesn't interfere with anything.
CLIENT :
import openSocket from 'socket.io-client';
let url = Store.config.socketserverurl + ":" + Store.config.socketserverport;
const socket = openSocket.connect(url);
Store is just the flux store that has the config files linked to it.
I have tried adding the webSockets method of using socket.io instead of the http method but that was in vain as an other problem spiraled.
what should I do ?

How to use socketio to send data to reactjs from express?

I have a simple authentication app to instagram. After I authenticate to instagram and receive user profile I would like to send the username from server side to reactjs client side. I tried using socket IO but I can't make it work.
Client side
componentDidMount() {
const { socket, provider } = this.props
console.log('component did mount')
socket.on(provider, user => { //provider is a string e.g 'instagram'
//receives data and update state.
this.setState({user})
})
}
startAuth() { //onclick function that opens up new window for auth
const {provider} = this.props
const width = 600, height = 600
const left = (window.innerWidth / 2) - (width / 2)
const top = (window.innerHeight / 2) - (height / 2)
const url = `https://localhost:5000/${provider}`
return window.open(url, '',
`toolbar=no, location=no, directories=no, status=no, menubar=no,
scrollbars=no, resizable=no, copyhistory=no, width=${width},
height=${height}, top=${top}, left=${left}`
)
}
Server side
//After successful authentication redirect here with username and provider as
//query string. Here I want to emit to my component and update component's state
app.get('/success', (req, res) => {
var provider = req.query.provider
var username = req.query.username
io.emit(provider, username); //this doesn't work
res.send('Auth to ' + provider + ' successful by ' + username)
})
What should I do in order for the emitted event in server side to get caught by the on inside componentDidMount()? I got no error messages whatsoever. I'm not even sure if the emitted event at /success got fired or not.
Socket connection works fine, I did the following code below and it works fine.
io.on('connection', (client) => {
client.on('subscribeToTimer', (interval) => {
console.log('client is subscribing to timer with interval', interval);
setInterval(() => {
client.emit('timer', new Date());
}, interval);
})
})
I faced a similar problem on a project I was working upon & the way I solved the problem was
Create file io.js
// singleton instance of socket.io that is stored here after the
// constructor function is called
let ioInstance;
module.exports = function(server) {
const io = require("socket.io")(server);
io.on("connection", socket => {
console.log("made socket connection", socket.id);
// Handle socket event
socket.on("eventTrigger", function(data) {
// console.log(data);
io.sockets.emit("chat", data);
});
});
// save in higher scope so it can be obtained later
ioInstance = io;
return io;
};
// this getIO method is designed for subsequent
// sharing of the io instance with other modules once the module has been initialized
// other modules can do: let io = require("./io.js").getIO();
module.exports.getIO = () => {
if (!ioInstance) {
throw new Error(
"Must call module constructor function before you can get the IO instance"
);
}
return ioInstance;
};
In file bin/www add below code
var app = require("../app");
var debug = require("debug")("express-sequelize");
var http = require("http");
var models = require("../models");
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || "3000");
app.set("port", port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
//initialize io
require("../io")(server);
server.listen(port, function() {
debug("Express server listening on port " + server.address().port);
});
server.on("error", onError);
server.on("listening", onListening);
now in route file for an api call if I wanted to send socket data
#file app.js
app.get('/success', (req, res) => {
const io = require("./io").getIO();
....
io.sockets.emit("eventTrigger",data);
res.send('Auth to ' + provider + ' successful by ' + username)
})
Hope this approach helps in fixing the issue that you are facing.

Resources