how to connect to socket.io on nodejs server using flutter? - node.js

I am developing a backend using node js and express framework and I will use socket.io in order to make a realtime connection between the server and the client ( flutter app ).
I have created a socket.io configuration on the server-side code and this is the code snippet:
const server = app.listen(port);
const io = require('socket.io')(server);
io.on('connection' , client => {
console.log('one connected');
});
and on the client side:
SocketIO socketIO;
socketIO = SocketIOManager().createSocketIO(SERVER_URL, '/');
socketIO.init().then(
(result) async {
await socketIO.subscribe('connection', (){});
await socketIO.connect();
},
);
the problem that I can't see one connected logged in the console of the node app.
it doesn't throw any error on the client-side and I want to know if I am on the right way.
Thanks,

After searching I found that the solution was to create my server using http plugin.

Related

How to call node function in angular application

I have this working code in node project
export function startWhatsapp(){
const qrcode = require('qrcode-terminal');
const { Client } = require('whatsapp-web.js');
const client = new Client();
client.on('qr', qr => {
qrcode.generate(qr, {small: true});
});
client.on('ready', () => {
console.log('Client is ready!');
});
client.initialize();
}
I need to use it in my angular app
what is the best practice to do it ?
You can use node web server, setup with express. It is quite easy to setup, then expose a simple API from the express server and use HttpClient from Angular to call the API.
https://expressjs.com/
If you want it more real time, based on the event, you can even use socket.io with node express server.
https://medium.com/#raj_36650/integrate-socket-io-with-node-js-express-2292ca13d891
You can use socket.io even on client side, so the it allow real time communication.

Websocket connection error : Does not return a 101 changing protocal when using from different path

I am using easy-rtc with socket.io for multiuser experience in my metaverse project. We maintain the connection in socket.io using polling and web-socket. I am facing problem in web-socket connection when I am trying to give path to the socket.io.
Firstly, I am putting forward the code where I am not using any path.
You can get the complete code from here. https://github.com/networked-aframe/networked-aframe/blob/master/server/easyrtc-server.js
The web-socket connection request which I am getting from this code is giving me a 101 changing protocols as expected.
I am even getting the response for the web-socket request as connecting in the Postman.
Now, My backend is working at localhost:3333/api/ . I am trying to change the path of socket.io in the client and server as shown in the images below. but I am not getting the 101 changing protocol response from web-socket connection request. This is the code after path change.
This is the client side code:
This is the backend code :
This is the response which I am getting when running the code after doing the path changes.
When I am trying to hit the web-socket request in the postman also I am not getting any connection. One observation I have made is that in the request URL, it is not taking the localhost:3333/api/ path. (If this is the issue, suggest any work arounds for this.)
Without getting the web-socket connection, the server is not efficient for communication.
Anyone suggest working solutions for this.
I was able to reproduce it.
A working solution
The problem is in your server code. You are doing something like this:
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const io = require('socket.io')(server, {path: '/api/socket.io'}) // here you are already attaching the socket.io server to the HTTP server
const socketServer = io.listen(server) // this line is not required!
The last line is not required. It should be used only with socket server istances not yet attached to any http server. In the previous line you are already importing the socket.io main function, calling it, attaching to the HTTP server.
Therefore, try removing the .listen call and you will receive the 101 changing protocol http status code again.
With the above proposed solution, you can listen on socket events directly using the io istance. Like this:
io.on('connection', (socket) => {
console.log('a user connected');
});
Why it was working without the path?
Well, the first code snipped you provided should not work at all. From what I can see you were doing this:
const socketIo = require('socket.io')
socketIo.listen(webServer, {"log level": 1})
The above code can't work. The socketIo variable is an anonymous function. The listen method is not defined. Are you sure you have not initialized the module in a different way? Maybe are you using and old version of socket.io?
A better approach
Anyway, I suggest the new fresh, clean syntax socket.io documentation suggests;
Backend:
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, {path: '/api/socket.io'});
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
console.log('a user connected');
});
server.listen(3000, () => {
console.log('listening on *:3000');
});
Client (I'm using a CDN but you could rely to your server for the socket.io-client code):
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="module">
import { io } from "https://cdn.socket.io/4.4.1/socket.io.esm.min.js";
const socket = io({path: "/api/socket.io"});
</script>
</body>
</html>

No response from Socket.io server when client is making a connection

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.

How to manage socket in client side as ejs template and react js and the server side it is nodejs

In my project use the reactJS for frontend and ejs template engine with a node for the backend. already the project is started so now I can't change the whole project into reactJS.
creating one chat app with two clients(react and ejs) and one server(nodeJs) but I stuck in message passing to both clients at one time.
my code is below please tell me is that possible to create a chat app with ejs, node, and react.
ejs:-
<script src="/backend/chat/socketMessage.js"></script>
var socket = io.connect('http://localhost:8080');
socket.on('receive-user',function(data){
console.log('receive on ejs');
})
reactJs:-
import io from 'socket.io-client';
const ENDPOINT = 'localhost:8080';
constructor() {
super();
endpoint:ENDPOINT,
}
const {endpoint} = this.state;
const socket = io(endpoint);
socket.on('receive-user', this._messageRecieve);
_messageRecieve(message) {
console.log(message)
}
nodeJS:-
module.exports = function(io) {
io.on('connection', function(socket){
socket.emit('receive-user',details);
})
}
Please Help...
use as per below it will work fine
io.on('connection', function(socket){
io.sockets.emit('receive-user',details);
})

Flutter socket io doesn't connect to node js socket io server

I'm trying to build a simple flutter chat application using a node.js matchmaking server. I've worked with this for a few hours already but I simple cannot get the app to connect with the server.
Here's the node js server:
var express=require('express');
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var allClients = {};
io.on('connection', function (socket) {
io.to(socket.id).emit('userCount', Object.keys(allClients).length);
console.log(socket.id,'joined');
//match making logic
});
var port = 8080;
console.log(port);
server.listen(port);
Flutter connecting code:
//Find a match for the user
void findMatch() async {
SocketIO socketIO = SocketIOManager().createSocketIO("http://192.168.0.32:8080", "/");
print('Created');
await socketIO.init(); //code execution pauses indefinitely at this line
print('Initialized');
await socketIO.connect();
print('Connected');
socketIO.sendMessage('new user', data);
socketIO.subscribe('match found', (data) async {
UserData peerData = await getUserData(data.peerId);
redirectToPage(context, Chat(peerId: data.peerId, peerData: peerData));
});
}
When the function is run, the code execution pauses at the line shown above, and the node js server doesn't react at all. However this shows up on the debug console.
D/FlutterSocketIoPlugin: FlutterSocketIoPlugin( 4490): onMethodCall: socketInit - domain: http://192.168.0.32:8080 - with namespace: /
D/FlutterSocketIoPlugin: TOTAL SOCKETS: ( 4490): 0
D/FlutterSocketIoPlugin: TOTAL SOCKETS: ( 4490): 0
D/FlutterSocketIoPlugin: added SocketIO( 4490): http://192.168.0.32:8080/
D/FlutterSocketIoPlugin: SocketIO( 4490): connecting...null
Any help is appreciated. Thank you!
I wrote a simple node js client as suggested in the comments, and it connects to the server successfully.
//client.js
var io = require('socket.io-client');
var socket = io.connect('http://localhost:8080', {reconnect: true});
// Add a connect listener
socket.on('connect', function (socket) {
console.log('Connected!');
});
socket.emit('CH01', 'me', 'test msg');
Edit:
Removing the 'await's before the socket functions in findMatch() gets me this.
D/FlutterSocketIoPlugin: SocketIO(21368): reconnect_error: [{"cause":{"cause":{"detailMessage":"CLEARTEXT communication to 192.168.0.32 not permitted by network security policy","stackTrace":[],"suppressedExceptions":[]},"detailMessage":"websocket error","stackTrace":[],"suppressedExceptions":[]},"detailMessage":"Connection error","stackTrace":[],"suppressedExceptions":[]}]
I tried android:usesCleartextTraffic="true" in AndroidManifest.xml but it doesn't seem to work. Changing http to https gives SSL handshake aborted. Maybe deploying the socket server on a remote machine with an SSL certificate will work? Will continue digging.
Downgrading my server's socket.io version worked for me. Just as above, if you are using nodejs try uninstalling socket.io and installing an older version as follows:
npm uninstall socket.io
npm install socket.io#2.3.0
Most flutter socket io client packages are compatible with socket.io version 2.3.0. I would recommend you downgrade to this incase you are experiencing a similar problem.
I tried above code with this flutter plugin here as I think you are also using the same, but I also got the same problem. I tried to see any error log generated by Logcat and I found an entry connecting...null and it was stuck there but don't know how to fix or what is the problem. I tried it with another flutter plugin here and tested it in emulator, it worked fine for below sample code. If you can use a different flutter plugin then this might be useful.
var express = require('express');
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
io.on('connection', function (socket) {
console.log(socket.id, 'joined');
socket.on('/test', function (msg) {
console.log(msg);
});
});
var port = 8080;
console.log(port);
server.listen(port);
Flutter client code -
IO.Socket socket = IO.io('http://10.0.2.2:8080', <String, dynamic>{
'transports': ['websocket'],
'autoConnect': false,
});
socket.connect();
socket.emit('/test', 'test');
Try downgrading your server's socket io version. Some socket io client packages(flutter) are not compatible with the latest server-side socket io (node.js). My server configuration was using version 3.0.4. For some reason, it was incompatible with adhara_socket_io: 0.4.2 and socket_io_client: 0.9.12. By downgrading my node.js socket io version worked for both client libraries
npm uninstall socket.io
npm install socket.io#2.3.0
work too
server(nodejs) => "socket.io": "^2.4.1"
client(flutter) => socket_io_client: ^1.0.1

Resources