【workerman】客户端使用workerman的AsyncTcpConnection发起异步连接,服务端提示Sec-WebSocket-Accept not found
问题背景:
1、客户端使用workerman的AsyncTcpConnection发起异步连接;
2、代理层使用nginx进行wss反向代理;
3、服务端使用workerman搭建websocket服务;
问题现象:
客户端使用workerman的AsyncTcpConnection发起异步连接,服务端提示Sec-WebSocket-Accept not found。
问题原因:
详见注意事项
解决方案:
1、客户端代码:
<?php use Workerman\Worker; use Workerman\Connection\AsyncTcpConnection; require_once dirname(__DIR__) . '/Workerman/Autoloader.php'; $worker = new Worker(); // 进程启动时 $worker->onWorkerStart = function() { // 设置访问对方主机的本地ip及端口以及ssl证书 $context_option = array( 'ssl' => array( //本地证书路径。 必须是 PEM 格式,并且包含本地的证书及私钥。 'local_cert' => '/tmp/test/workerman.crt', //私钥 'local_pk' => '/tmp/test/workerman.key', //是否需要验证 SSL 证书。 'verify_peer' => false, //是否允许自签名证书。 'allow_self_signed' => true, ) ); // 以websocket协议连接远程websocket服务器, 特别注意: SSL是针对域名的!!!!!!!!!!!!!!!!! $ws_connection = new AsyncTcpConnection("ws://www.wss.com:443/wss", $context_option); // 设置以ssl加密方式访问,使之成为wss $ws_connection->transport = 'ssl'; // 连上后发送hello字符串 $ws_connection->onConnect = function($connection){ echo "send: hi\n"; $connection->send('hi'); }; // 远程websocket服务器发来消息时 $ws_connection->onMessage = function($connection, $data){ echo "recv: $data\n"; }; // 连接上发生错误时,一般是连接远程websocket服务器失败错误 $ws_connection->onError = function($connection, $code, $msg){ echo "error: $msg\n"; }; // 当连接远程websocket服务器的连接断开时 $ws_connection->onClose = function($connection){ echo "connection closed\n"; }; // 设置好以上各种回调后,执行连接操作 $ws_connection->connect(); }; Worker::runAll();2、nginx关于wss配置:
server { listen 443; server_name www.wss.com; ssl on; ssl_certificate /tmp/test/workerman.pem; ssl_certificate_key /tmp/test/workerman.key; ssl_session_timeout 5m; ssl_session_cache shared:SSL:50m; ssl_protocols SSLv3 SSLv2 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; location /wss { proxy_pass http://127.0.0.1:5678; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header X-Real-IP $remote_addr; } location / { } }3、服务端代码:
<?php use Workerman\Worker; use Workerman\Lib\Timer; require_once dirname(__DIR__) . '/Workerman/Autoloader.php'; // 注意:这里与上个例子不通,使用的是websocket协议 $worker = new Worker("websocket://0.0.0.0:5678"); // 启动4个进程对外提供服务 $worker->count = 4; // 3次握手OK $worker->onConnect = function($connection) { $connection->onWebSocketConnect = function($connection , $http_header){ //pprint($_GET, $_POST, $_REQUEST, $_COOKIE, $_SERVER); }; }; // 当收到客户端发来的数据后返回hello $data给客户端 $worker->onMessage = function($connection, $data) { if(empty($data)) { $client_ip = $connection->getRemoteIp(); $client_port = $connection->getRemotePort(); $client_id = '|' . $connection->worker->id . '|' . $connection->id; $connection->send($client_ip . ":" . $client_port . $client_id); } else { pprint('recv data from client: ' . $data); $connection->send($data . ' <- reply'); } }; // 连接关闭时,删除对应连接的定时器 $worker->onClose = function($connection) { }; // 运行worker Worker::runAll();
注意事项:
1、例子中的 www.wss.com 一定要在本地做 hosts 映射
2、ngnix已经做了wss代理,所以服务端代码禁止设置:
$worker->transport = 'ssl';
版权声明:除非注明,本文由( blogdaren )原创,转载请保留文章出处。
本文链接:【workerman】客户端使用workerman的AsyncTcpConnection发起异步连接,服务端提示Sec-WebSocket-Accept not found
发表评论: