Flutter Socket io disconnects after some seconds - node.js

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(
...
));
}

Related

Get data from NodeJS to Dart/Flutter using Socket.io

I'm trying to get data from the NodeJS and I've no idea how to do this can someone help me? The packages used in this example are: import 'dart:async' and import 'package:socket_io_client/socket_io_client.dart';
testSocket.dart
void testSocket(socket) async {
Socket socket;
try {
// Configure socket transports must be sepecified
socket = io('http://127.0.0.1:3000', <String, dynamic>{
'transports': ['websocket'],
});
// Connect to websocket
socket.connect();
// THIS IS WHERE I WANT TO PRINT THE DATA THAT WE GOT RECIEVED FROM NODEJS
socket.on('event', (data) => print(data));
}
print("connected: ${socket.connected}");
}
index.js
const server = require('http').createServer()
const io = require('socket.io')(server)
io.on('connection', function (client) {
client.on('event', function name(data) {
data = "test";
// Send data somehow to Flutter
io.on();
});
});
// The live server
var server_port = process.env.PORT || 3000;
server.listen(server_port, function (err) {
if (err) throw err
console.log('Listening on port %d', server_port);
});
I really appreciate it that you are taking time to help me out!
You have to emit events from your server and your client has to subscribe to those same events in order to receive data and updates.
testSocket.dart
void testSocket(socket) async {
Socket socket;
try {
socket = io('http://127.0.0.1:3000', <String, dynamic>{
'transports': ['websocket'],
});
socket.connect();
socket.on('testEvent', (data) => print(data));
}
print("connected: ${socket.connected}");
}
And your server has to then emit the testEvent with some data.
index.js
const server = require('http').createServer()
const io = require('socket.io')(server)
io.on('connection', function (client) {
client.on('event', function name(data) {
data = "test";
client.emit('testEvent', data);
});
});
var server_port = process.env.PORT || 3000;
server.listen(server_port, function (err) {
if (err) throw err
console.log('Listening on port %d', server_port);
});
Now since we're firing just a one-off event, the data will only come once. You'd have to emit the same event in order for the clients to receive updates.

React client receives two connections using Socket.io

I am developing a simple app with SocketIO and I am encountering this problem. In the server I have the following code:
const httpServer = require('http').createServer();
const socketIO = require('socket.io');
const port = process.env.PORT_WS || 5001;
const io = socketIO(httpServer, { cors: { origin: '*' } });
io.on('connection', (socket) => {
console.log('Connected to socket');
socket.on('join-room', () => {
console.log('joined room')
});
});
httpServer.listen(port, () => {
console.log(`Listening on the port ${port}`);
});
In the client I have the following code:
import { io } from 'socket.io-client';
export default class SocketConnection {
constructor() {
this.initializeSocketConnection();
this.initializeSocketEvents();
}
initializeSocketConnection() {
console.log('I am here');
this.socket = io('ws://localhost:5001');
}
initializeSocketEvents() {
this.socket.on('connect', () => {
console.log('Socket connected');
});
}
}
I get in the console two Socket connected messages.
This is not a re-render issue because the I am here message is logged only once.
I am using socket.io version 4.0.1 both in the client and in the backend.
So this is happening because, in React Strict Mode, constructors are called two times. React seems to hide this. As the console.log('Socket connected'); is inside an "on" event, React has no way to "hide" this. Thus, 'I am here' is going to be shown once but 'Socket connected' is going to be shown twice.

io.sockets.emit() won't work in production

I am trying to setup a socket in production like so:
client :
import openSocket from 'socket.io-client';
function handleSomething() {
let socketServer = 'https://staging.app.xxx.eu:9999';
const socket = openSocket(socketServer);
socket.on('calendlyHook', () => {
console.log("*** HERE");
...
socket.emit('closeSocket');
socket.close();
socket.removeAllListeners();
});
}
server :
const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
function openSocket() {
io.close();
io.set('origins', '*:*');
io.on('connection', (client) => {
console.log('Socket connected');
client.on('closeSocket', () => {
io.close();
io.removeAllListeners();
console.log('Socket closed');
});
});
const port = 9999;
io.listen(port);
console.log('*** listening on port ', port);
}
Then server-side, another function tries the following:
io.emit('calendlyHook');
or
io.sockets.emit('calendlyHook');
I have several issues in production (none of which happen on localhost):
console.log('*** listening on port ', port) is working fine
console.log('Socket connected') is not happening
io.emit('calendlyHook') or io.sockets.emit('calendlyHook') are not doing anything
I do not have any web server proxy set up on that url.
What is wrong here? Thanks!

Not able to connect to nodeJS socket.io server on localHost using flutter client

i'm trying to stabilish a connection between a nodeJS server and a flutter app but I always receive connect_error on client side. If I try to connect by the browser, it's successful, so i think the problem is on client side.
My nodeJS server:
const app = require('express')()
const http = require('http').createServer(app)
var io = require('socket.io')(http)
io.on('connection', (client) => {
console.log('a user connected')
client.on('message', (data) => {
console.log('Message received --> ', data)
// io.emit('chat', data)
})
})
http.listen(5000, () => {
console.log('Listening on port 5000')
})
Client side is implemented using socket_io_client package on InitState as follows:
import 'package:socket_io_client/socket_io_client.dart' as IO;
IO.Socket socket;
#override
void initState() {
//on xxx.xxx.xxx.xxx i'm inserting my local ip address
socket = IO.io('http//xxx.xxx.xxx.xxx:5000/', <String, dynamic>{
'transports': ['websocket']
});
socket.connect();
socket.on("connect", (_) => print('Connected'));
socket.on("connect_error", (data) => print('connect_error: ' + data));
super.initState();
}
The client keeps showing the output "connect_error: timeout".
Anybody can help? Thanks in advance.
Edit1: Also tried to disable windows firewall but it didn't help.

Node.js client for a socket.io server

I have a socket.io server running and a matching webpage with a socket.io.js client. All works fine.
But, I am wondering if it is possible, on another machine, to run a separate node.js application which would act as a client and connect to the mentioned socket.io server?
That should be possible using Socket.IO-client: https://github.com/LearnBoost/socket.io-client
Adding in example for solution given earlier. By using socket.io-client https://github.com/socketio/socket.io-client
Client Side:
//client.js
var io = require('socket.io-client');
var socket = io.connect('http://localhost:3000', {reconnect: true});
// Add a connect listener
socket.on('connect', function (socket) {
console.log('Connected!');
});
socket.emit('CH01', 'me', 'test msg');
Server Side :
//server.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
io.on('connection', function (socket){
console.log('connection');
socket.on('CH01', function (from, msg) {
console.log('MSG', from, ' saying ', msg);
});
});
http.listen(3000, function () {
console.log('listening on *:3000');
});
Run :
Open 2 console and run node server.js and node client.js
After installing socket.io-client:
npm install socket.io-client
This is how the client code looks like:
var io = require('socket.io-client'),
socket = io.connect('http://localhost', {
port: 1337,
reconnect: true
});
socket.on('connect', function () { console.log("socket connected"); });
socket.emit('private message', { user: 'me', msg: 'whazzzup?' });
Thanks alessioalex.
const io = require('socket.io-client');
const socket_url = "http://localhost:8081";
let socket = io.connect(socket_url);
socket.on('connect', function () {
socket.emit("event_name", {});
});
Yes you can use any client as long as it is supported by socket.io. No matter whether its node, java, android or swift. All you have to do is install the client package of socket.io.
Client side code: I had a requirement where my nodejs webserver should work as both server as well as client, so i added below code when i need it as client, It should work fine, i am using it and working fine for me!!!
const socket = require('socket.io-client')('http://192.168.0.8:5000', {
reconnection: true,
reconnectionDelay: 10000
});
socket.on('connect', (data) => {
console.log('Connected to Socket');
});
socket.on('event_name', (data) => {
console.log("-----------------received event data from the socket io server");
});
//either 'io server disconnect' or 'io client disconnect'
socket.on('disconnect', (reason) => {
console.log("client disconnected");
if (reason === 'io server disconnect') {
// the disconnection was initiated by the server, you need to reconnect manually
console.log("server disconnected the client, trying to reconnect");
socket.connect();
}else{
console.log("trying to reconnect again with server");
}
// else the socket will automatically try to reconnect
});
socket.on('error', (error) => {
console.log(error);
});
something like this worked for me
const WebSocket = require('ws');
const ccStreamer = new WebSocket('wss://somthing.com');
ccStreamer.on('open', function open() {
var subRequest = {
"action": "SubAdd",
"subs": [""]
};
ccStreamer.send(JSON.stringify(subRequest));
});
ccStreamer.on('message', function incoming(data) {
console.log(data);
});

Resources