My app in Flutter integrates a chat with Socket.io and does not connect to a remote server

Viewed 1358

Develop a flutter application that includes a chat that uses Socket.io

The server is hosted by an EC2 instance on AWS. I did a test first on my local computer.

Create a server with socket.io and a web client to test the connection, It worked fine.

Server code:

const path = require("path");
const http = require('http');
const express = require("express");
const socketio = require("socket.io");
const app = express();



app.set('port', 3000);

//static files

app.use(express.static(path.join(__dirname, "public")));

//start the server
const server = app.listen(app.get('port'), () => {

    console.log("server on port", app.get('port'));

});

const server2 = http.createServer(server);

const io = socketio(server);

//websockects

io.on('connection', (socket) => {


    console.log("new connection  " + socket.id);
    console.log(socket);


    socket.on('chat:message', (data) => {
        console.log(data.constructor.name);
        console.log(data);


        io.sockets.emit("chat:server", data);

    });

    socket.on('chat:typing', (data) => {
        console.log(data);

        socket.broadcast.emit("chat:typing", data);

    });

    socket.on('message', (data) => {
        console.log(data.constructor.name);
        console.log(data);


        io.sockets.emit("news", { respuesta: "Recibio" });

    });
});

Client code:

///coneccion al servidor
const socket = io();

//dom elements
let message = document.getElementById("message");
let username = document.getElementById("username");
let btn = document.getElementById("button");
let output = document.getElementById("output");
let actions = document.getElementById("actions");

//evento de envio de mensaje
btn.addEventListener('click', function() {
    console.log({
        username: username.value,
        message: message.value
    });
    //socket que emite el mensaje al servidor
    socket.emit("chat:message", {
        username: username.value,
        message: message.value
    });
});


//Escuchador de teclado, se activa cuando el usuario teclea
message.addEventListener('keypress', function() {
    //emite  el nombre del usuario cuando este esta teclando al lado del cliente
    socket.emit("chat:typing", username.value);
    socket.emit("message", username.value);
});

//socket que recibe los mensajes del servidor
socket.on("chat:server", function(data) {
    console.log(data);
    actions.innerHTML = "";
    output.innerHTML += "<p><strong>" + data.username + "</strong>: " + data.message + " </p>";

});

//socket que recibe el nombre del usuario que esta teclando
socket.on("chat:typing", function(data) {
    console.log(data);
    actions.innerHTML = "<p><strong>" + data + "</strong> esta escribiendo </p>";

});

socket.on("news", function(data) {
    console.log(data);

});

After this, I uploaded the server code to the EC2 instance. The server uses NGINX, I had to modify it so that it accepted connections from outside the server, like this:

Access-Control-Allow-Origin: *

I just modify the connection socket of the client:

const socket = io("https://mycustomdomain.org");

And worked, from my pc I connect to the server. Now my problem is with flutter. I tried with two libraries:

-https://pub.dev/packages/socket_io_client -https://pub.dev/packages/adhara_socket_io

With neither of the two libraries I can connect to the server. In localhost it worked but when i Tried to connect to EC2 server i cant connect.

I made the simple example of each library,

With Adhara:

Future<void> socketConfig() async {
        SocketIOManager manager = SocketIOManager();
        SocketIO socket = await manager.createInstance('https://mycustomdomain.org');       //TODO change the port  accordingly
        socket.onConnect((data){
          print("connected...");
          print(data);
          socket.emit("message", ["Hello world!"]);
        });
        socket.on("news", (data){   //sample event
          print("news");
          print(data);
        });
        socket.connect();
        ///disconnect using
        ///manager.
    }

    socketConfig();

And with socket.io-client

import 'package:socket_io/socket_io.dart';
import 'package:socket_io_client/socket_io_client.dart' as IO;

main() {
    // Dart server
    var io = new Server();
    var nsp = io.of('/some');
    nsp.on('connection', (Socket client) {
      print('connection /some');
      client.on('msg', (data) {
        print('data from /some => $data');
        client.emit('fromServer', "ok 2");
      });
    });
      io.on('connection', (Socket client) {
        print('connection default namespace');
        client.on('msg', (data) {
          print('data from default => $data');
          client.emit('fromServer', "ok");
        });
      });
      io.listen(3000);

    // Dart client
    IO.Socket socket = IO.io('https://mycustomdomain.org/');
    socket.onConnect((_) {
     print('connect');
     socket.emit('msg', 'test');
    });
    socket.on('event', (data) => print(data));
    socket.onDisconnect((_) => print('disconnect'));
    socket.on('fromServer', (_) => print(_));
}

It didn't even manage to detect them connecting to the server. By the way, my domains has SSL certificates.

Any idea what might be going on?

1 Answers

My node.js project was using socket.io version 3.0.0 (the latest), but it looks like my flutter client doesn't support it, so try to downgrade to version 2.3.0 (don't do it manually, in other words don't modify the file manually)

npm uninstall socket.io
npm install socket.io@2.3.0

And

For some reason the "autoConnect" not work, so try to connect it manually.

IO.Socket socket = IO.io('https://mycustomdomain.org', <String, dynamic>{
    'transports': ['websocket'],
    'autoConnect': false,
});
    
// Dart client
socket.on('connect', (_) {
    print('connect');
});
socket.on('event', (data) => print(data));
socket.on('disconnect', (_) => print('disconnect'));
socket.on('fromServer', (_) => print(_));

// add this line
socket.connect();
Related