websocket + php + nginx - 超级简单

Posted

技术标签:

【中文标题】websocket + php + nginx - 超级简单【英文标题】:websocket + php + nginx - super simple 【发布时间】:2018-08-27 14:48:36 【问题描述】:

我正在尝试在 php + nginx 上设置超级简单的 websocket

nginx

server 
    listen 8443 ssl;
    server_name  websocket.example.com;

    root  /var/www/public/websocket;

    ssl_certificate  /var/ini/ssl/public.crt;
    ssl_certificate_key  /var/ini/ssl/private.key;

    error_log  /var/log/nginx/error_websocket.log warn;

    location / 
        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;
    

客户

var host = 'wss://websocket.dyntest.dk:8443';
var socket = new WebSocket(host);
socket.onmessage = function(e)
    document.getElementById('ws_test').innerhtml = e.data;
    console.log(e.data);
;

服务器

$address = '127.0.0.1';
$port = 9000;
// Create WebSocket.
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($server, $address, $port);
socket_listen($server);
$client = socket_accept($server);
// Send WebSocket handshake headers.
$request = socket_read($client, 5000);
preg_match('#Sec-WebSocket-Key: (.*)\r\n#', $request, $matches);
$key = base64_encode(pack(
    'H*',
    sha1($matches[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
));
$headers = "HTTP/1.1 101 Switching Protocols\r\n";
$headers .= "Upgrade: websocket\r\n";
$headers .= "Connection: Upgrade\r\n";
$headers .= "Sec-WebSocket-Version: 13\r\n";
$headers .= "Sec-WebSocket-Accept: $key\r\n\r\n";
socket_write($client, $headers, strlen($headers));
// Send messages into WebSocket in a loop.
while (true)
    sleep(1);
    $content = 'Now: ' . time();
    $response = chr(129) . chr(strlen($content)) . $content;
    socket_write($client, $response);

启动 websocket 服务器

php -q public/websocket/index.php

错误

在浏览器中:wss://websocket.example.com:8443/

ERR_DISALLOWED_URL_SCHEME

【问题讨论】:

你能澄清你的问题吗?该错误是写在 shell 中、浏览器中、日志文件中的某处……吗? 请求wss://websocket.example.com:8443/时浏览器返回错误 【参考方案1】:

浏览器似乎不信任您的证书,这不允许您访问 WebSocket。您需要将 CA 添加到您的计算机/浏览器的信任库或获取受信任的证书。如果您确实想要一个受信任的证书,您可以使用Let's Encrypt,或者您可以从任何数量的销售此类产品的公司购买 SSL 证书。

要添加到您机器的信任库,请尝试以下链接(其基本前提是找到浏览器存储 CA/Cert 信息的位置并手动添加您的):

Getting Chrome to accept self-signed localhost certificate https://support.mozilla.org/en-US/questions/1059377

根据您提供的新信息,您可能需要修复您的 nginx 配置,在 nginx 配置中添加 Web 套接字位置作为直通。

location /websocket/ 

proxy_pass ​http://backend_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;

【讨论】:

我现在已切换到受信任的证书,但它仍然无法正常工作

以上是关于websocket + php + nginx - 超级简单的主要内容,如果未能解决你的问题,请参考以下文章

通过 php-cli 运行 websocket 服务器 stop php-fpm 以响应 nginx

PHP站点和NodeJS Websocket应用程序在同一个Nginx服务器/配置后面

Nginx支持WebSocket服务

nginx websocket proxy

我应该使用nginx作为WAMP的代理吗?

nginx websocket握手不起作用,配置错误?