【问题标题】:PHP websockets with nginx via SSL通过 SSL 使用 nginx 的 PHP websockets
【发布时间】:2017-06-10 01:09:15
【问题描述】:

如何在 nginx 中使用 PHP 设置 websockets?

我看过这个教程,但不能让它工作

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

已将三个文件复制到www目录的根目录

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

index.php我已经更改了URI

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

在 nginx 我已经添加了这个

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

启动 websocket 服务器

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

聊天位于https://domain.com/chat.php 并加载,但在聊天窗口Error Occurred - Connection closed 中出现此错误

也尝试通过这个工具连接,但得到这个错误

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

ERROR: undefined
DISCONNECTED

如果通过浏览器请求

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


ERR_DISALLOWED_URL_SCHEME

【问题讨论】:

  • 我假设错误显示在浏览器窗口中,而不是 nginx 或 php 日志中。你有没有机会使用谷歌浏览器来测试这个(productforums.google.com/forum/#!topic/chrome/leVmLPNVISI)?如果是这样,请尝试使用其他浏览器。
  • 是的,谷歌Chrome浏览器出现错误。。也试过FF。。这里我什至没有收到错误
  • 尝试窃听您的客户端和 nginx 以及 nginx 和 php 之间的流量,例如,使用例如tcpdump 检查设置是否在网络级别按预期工作。
  • @TomRegner 你能给我一个例子吗?
  • 在 SO 上搜索“tcpdump websocket”,你会发现的讨论应该让你继续前进

标签: php nginx websocket


【解决方案1】:

我在您的配置文件中发现了一些小故障;我的观察如下:

  • 运行php -q /var/www/websocket/server.php 将启动简单的套接字服务器。它不会是 SSL;我想这就是你通过 nginx 传递它的原因。不是吗?
  • 因此proxy_pass https://domain.com:9000/websocket/server.php; 不应该是https。您也不需要完整路径,因为它是一个简单的 tcp 套接字而不是文件路径。因此,只需 proxy_pass http://127.0.0.1:9000; 即可。
  • 如果你在 nginx 上实现 SSL;这些设置在哪里?
  • 在所有新浏览器中;您无法从安全的 https 页面访问不安全的 http 或 ws 资源。

因此以下是我的配置文件,它似乎按预期工作。

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

还将index.php 更改为var wsUri = "wss://localhost:8443/websocket/";

【讨论】:

    【解决方案2】:

    您在 nginx 配置中使用端口 9000,而 PHP 的内置 Web 服务器在端口 8000 上运行。

    尝试将端口更改为 8000 看看是否可以解决问题。

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

    编辑:

    关于 ERR_DISALLOWED_URL_SCHEME

    Chrome,从〜版本 50 开始,要求所有 websocket 通信都通过 SSL。您可能需要启用它才能让您的应用在 Chrome 中运行。

    你有两个选择:

    1. 使用由受信任的证书颁发机构颁发的证书
    2. 手动将证书添加到受信任的证书根目录。不手动执行此操作的任何人都无法使用您的网络应用程序

    【讨论】:

    • 在请求websocket URL ERR_DISALLOWED_URL_SCHEME时得到同样的错误
    • 现在已经更改了 nginx 中的配置以运行 SSL,但仍然得到相同的错误
    • 您使用的证书是自签名的吗? Chrome 也可能因为这个原因拒绝它
    • @clarkk 我已根据您的评论修改了我的答案
    • 我现在正在使用受信任的证书.. 同样的问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    • 2017-09-27
    相关资源
    最近更新 更多