Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP websockets with nginx via SSL

How to setup websockets with PHP in nginx?

I have looked at this tutorial, but cant make it work

https://www.sanwebe.com/2013/05/chat-using-websocket-php-socket

Have copied the three files into the root of the www directory

/index.php /jquery-3.1.1.js /websocket/server.php

In index.php I have changed the URI

var wsUri = "wss://domain.com/websocket/server.php";

In nginx I have added this

http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }
    server {
        location /websocket/ {
            proxy_pass https://domain.com:9000/websocket/server.php;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
        }
    }
}

http://nginx.org/en/docs/http/websocket.html

To start websocket server

php -q /var/www/websocket/server.php

The chat is located at https://domain.com/chat.php and loads but get this error in the chat window Error Occurred - Connection closed

Have also tried to connect through this tool, but get this error

http://www.websocket.org/echo.html

ERROR: undefined
DISCONNECTED

If requested through browser

wss://domain.com/websocket/server.php


ERR_DISALLOWED_URL_SCHEME
like image 536
clarkk Avatar asked Jan 25 '17 00:01

clarkk


2 Answers

I have spotted few glitches in your config file; my observations are as follows:

  • Running php -q /var/www/websocket/server.php will start simple socket server. It won't be SSL; i guess thay's why you are passing it through nginx. isn't it?
  • Thus proxy_pass https://domain.com:9000/websocket/server.php; should not be https. You also don't need the full path as it's a simple tcp socket and not a file path. Thus just proxy_pass http://127.0.0.1:9000; should do.
  • If you are implementing SSL at nginx; where are those settings?
  • In all new browsers; you can't access unsecured http or ws resources from a secured https page.

Thus following is my config file which seems to be working as intended.

 server {
    listen 8080 default_server;
    listen 8443 ssl;

    ssl_certificate /home/ubuntu/Desktop/php-sock/newcert.pem;
    ssl_certificate_key /home/ubuntu/Desktop/php-sock/newkey.pem;

    root /home/ubuntu/Desktop/php-sock;

    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    location /websocket/ {
        proxy_pass http://127.0.0.1:9000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;
    }
}

Also make change in index.php to var wsUri = "wss://localhost:8443/websocket/";

like image 135
Malay Sarkar Avatar answered Sep 20 '22 02:09

Malay Sarkar


You're using port 9000 in your nginx configuration, while PHP's built-in web server runs on port 8000.

Try change the port to 8000 and see if that resolves it.

proxy_pass http://domain.com:8000/websocket/;

Edit:

Regarding ERR_DISALLOWED_URL_SCHEME

Chrome, since ~version 50, requires that all websocket communication be over SSL. You're probably going to need to enable that in order to have your app work in Chrome.

You have two options:

  1. Use a certificate issued by a trusted certificate authority
  2. Add the certificate manually to your trusted certificate roots. Your web application won't work for anyone who doesn't do this manually
like image 40
Karl Buys Avatar answered Sep 20 '22 02:09

Karl Buys