socket.io-client-dart icon indicating copy to clipboard operation
socket.io-client-dart copied to clipboard

Solution for https and reverse proxy - WORKS

Open markosole opened this issue 1 year ago • 11 comments

Hi all,

After 3 days of searching and digging around, I've finally made compatible (mixture) setup between NodeJS Server + Client + Flutter client that work over HTTPS. Many of you had or still have same problem and here is short and sweet how to set it up with Apache reverse proxy forwarding

Server

Short and simple

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

http.listen(5003, () => console.log('Socket server served on port: 5003'));

NodeJS Client

Works with https with transports set to polling and without specified port number. Sidenote: NodeJS client does not work with websocket transports. It has to be set to "polling" mode or not set at all (default is polling)


var ios = require('socket.io-client');
var socketClient = ios.connect('https://domain.com', {
    reconnect: true,
    secure: true,
    rejectUnauthorized : false,
    transports: ['polling']

});

Flutter Client

Works with http and on specified port:

IO.Socket socket = IO.io('http://domain.com:5003',  
    OptionBuilder()  
        .setTransports(['websocket'])  
        .build());  
  
socket.connect();

Works with HTTPS:

IO.Socket socket = IO.io('https://domain.com',  
    OptionBuilder()  
        .setTransports(['websocket'])  
        .build());  
  
socket.connect();

Apache config - common setups

This does not work for Flutter client on https. Use another one below.

    ProxyPass / http://127.0.0.1/
    RewriteEngine on
    RewriteCond %{HTTPS:Upgrade} =websocket
    RewriteRule /(.*) "http://127.0.0.1:5003/$1" [P,L]
    RewriteCond %{HTTP:Upgrade} !=websocket
    RewriteRule /(.*) "http://127.0.0.1:5003/$1" [P,L]

Apache config - Flutter compatible

Keep in mind to add ws:// instead http:// as on example above

    RewriteEngine On    
    # Needed for Flutter app
    RewriteRule /(.*)           ws://localhost:5003/$1 [P,L]

    # Needed for NodeJS clients
    ProxyPass / http://localhost:5003/
    ProxyPassReverse / http://localhost:5003/

Versions used

NodeJS socket.io server: 4.6.0 NodeJS socket.io-client: 4.6.0 Flutter socket_io_client package: 2.0.1

Drop a comment if you have questions and suggestions. Cheers

markosole avatar Feb 14 '23 01:02 markosole

@markosole Hello. How can I edit rules for Nginx? I can connect my remote server socket via javascript client but not via Flutter.

sametserpil avatar Mar 07 '23 11:03 sametserpil

@sametserpil is your server Apache or Nginx and do you have access to config? - I am not Apache (and even less Nginx) expert but I'll try to help.

markosole avatar Mar 07 '23 20:03 markosole

Yeah server is mine and I've setup Nginx for reverse proxy. It's also not working with ip:port combination. Here are my logs:

My NodeJS socket.io version -> "socket.io": "^4.6.1", My Flutter socket.io client version -> socket_io_client: ^2.0.1

opening https://my-host-url-here I/flutter ( 9768): FINE: 2023-03-07 14:47:11.806365: creating transport "polling" I/flutter ( 9768): FINE: 2023-03-07 14:47:11.813039: setting transport websocket I/flutter ( 9768): FINE: 2023-03-07 14:47:11.814809: connect attempt will timeout after 20000 I/flutter ( 9768): FINE: 2023-03-07 14:47:11.956447: socket close with reason: "transport close"

sametserpil avatar Mar 08 '23 06:03 sametserpil

Can you paste your:

  1. Ngix configuration
  2. Flutter socket connection part
  3. Node JS server / Client connection part of the code

It's missconfiguration or missmatch of versions.

markosole avatar Mar 08 '23 23:03 markosole

Found the solution. It works with following nginx configuration and manual connection. @markosole thanks for the help.

    location / {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $host;

      proxy_pass http://localhost:3000;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }

sametserpil avatar Mar 09 '23 07:03 sametserpil

@sametserpil what's the equivalent for apache?

ROBERT-MCDOWELL avatar Jun 28 '23 14:06 ROBERT-MCDOWELL

FYI:

  • https://socket.io/docs/v3/reverse-proxy/
  • https://socket.io/docs/v4/reverse-proxy/

jumperchen avatar Oct 17 '23 03:10 jumperchen

Connection Error: WebSocketException: Connection to 'https://example.com:0/socket.io/?EIO=4&transport=polling#' was not upgraded to websocket

I am facing same issue. I have used socket_io_client: ^2.0.3+1 and from backend i have used 4.7.3 version of node and i have also set code necessary for server. but still can't connect

Jimesh843 avatar Nov 30 '23 14:11 Jimesh843

@Jimesh843 transport=polling only supports under web environment.

jumperchen avatar Dec 01 '23 01:12 jumperchen

then i need to use transport as websocket instaed of pooling?

socket = IO.io( 'https://example.com', <String, dynamic>{ 'autoConnect' : false, 'transports' : ['websocket'], 'extraHeaders': {'foo': 'bar'}, }, );

is it relevant?

Output: Connection Error: WebSocketException: Connection to 'https://example.com:0/socket.io/?EIO=4&transport=websocket#' was not upgraded to websocket

Still I am getting this error should i need to give any thing on server side or any permission from my side

Jimesh843 avatar Dec 01 '23 04:12 Jimesh843

then i need to use transport as websocket instaed of pooling?

socket = IO.io( 'https://example.com', <String, dynamic>{ 'autoConnect' : false, 'transports' : ['websocket'], 'extraHeaders': {'foo': 'bar'}, }, );

is it relevant?

Output: Connection Error: WebSocketException: Connection to 'https://example.com:0/socket.io/?EIO=4&transport=websocket#' was not upgraded to websocket

Still I am getting this error should i need to give any thing on server side or any permission from my side

Please help to solve this issue

Jimesh843 avatar Dec 06 '23 06:12 Jimesh843