Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solution for https and reverse proxy - WORKS #319

Open
markosole opened this issue Feb 14, 2023 · 11 comments
Open

Solution for https and reverse proxy - WORKS #319

markosole opened this issue Feb 14, 2023 · 11 comments
Labels

Comments

@markosole
Copy link

markosole commented Feb 14, 2023

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

@sametserpil
Copy link

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

@markosole
Copy link
Author

@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.

@sametserpil
Copy link

sametserpil commented Mar 8, 2023

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"

@markosole
Copy link
Author

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.

@sametserpil
Copy link

sametserpil commented Mar 9, 2023

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";
    }

@ROBERT-MCDOWELL
Copy link

@sametserpil
what's the equivalent for apache?

@jumperchen
Copy link
Member

@Jimesh843
Copy link

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

@jumperchen
Copy link
Member

@Jimesh843
transport=polling only supports under web environment.

@Jimesh843
Copy link

Jimesh843 commented Dec 1, 2023

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
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants