You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Workerman实现UNIX套接字服务端客户端连接异常求助

问题分析
  • 客户端核心错误:误用Workerman\Worker创建服务端实例,而非发起客户端连接
  • 路径错误:客户端socket路径与服务端不匹配,且错误将资源名追加到socket路径中(服务端socket是/var/www/html/sw/tmp.sock,客户端却指向/var/www/html/sw/app/Http/Controllers/tmp.sock/admin)
正确解决方案

方案1:使用Workerman异步TCP连接(HTTP协议,适合CLI环境)

Workerman提供AsyncTcpConnection用于客户端连接,由于服务端是HTTP接口,需构造标准HTTP请求报文。

public function index(Request $request)
{
    $time_start = microtime(true);
    $results = [];

    try {
        $search = $request->input('search');
        // 与服务端一致的Unix socket路径
        $socketPath = 'unix://' . base_path('tmp.sock');

        foreach ($search as $resource) {
            // 创建异步TCP连接,指定服务端socket
            $connection = new \Workerman\Connection\AsyncTcpConnection($socketPath);
            // 构造HTTP GET请求,对应服务端的/{name}路由
            $connection->send("GET /{$resource} HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n");
            
            // 处理服务端返回结果
            $connection->onMessage = function ($conn, $data) use (&$results, $resource) {
                // 拆分HTTP响应头与响应体
                list($header, $body) = explode("\r\n\r\n", $data, 2);
                $results[$resource] = json_decode($body, true) ?: $body;
                $conn->close();
            };

            // 发起连接
            $connection->connect();
        }

        // 启动Workerman事件循环,等待所有请求处理完成(仅适合CLI环境)
        \Workerman\Worker::runAll();
    } catch (\Exception $e) {
        return response($e->getMessage(), 500);
    }

    $time_end = microtime(true);
    $execution_time = ($time_end - $time_start);

    return view('search', compact('results', 'execution_time'));
}

注意:该方案依赖Workerman事件循环,会阻塞进程,不适合Web请求环境,仅用于CLI脚本场景。

方案2:使用Guzzle同步HTTP客户端(适合Web环境)

服务端基于HTTP协议,Guzzle支持直接连接Unix套接字,是Web环境下的最优选择。

  1. 先安装Guzzle:
composer require guzzlehttp/guzzle
  1. 客户端代码:
use GuzzleHttp\Client;

public function index(Request $request)
{
    $time_start = microtime(true);
    $results = [];

    try {
        $search = $request->input('search');
        // 服务端Unix socket的绝对路径
        $socketPath = base_path('tmp.sock');

        $client = new Client([
            'base_uri' => 'http://localhost',
            'curl' => [
                // 指定Unix套接字路径
                CURLOPT_UNIX_SOCKET_PATH => $socketPath,
            ],
        ]);

        foreach ($search as $resource) {
            // 发起GET请求,对应服务端的/{name}路由
            $response = $client->get("/{$resource}");
            $results[$resource] = json_decode($response->getBody(), true) ?: $response->getBody()->getContents();
        }
    } catch (\Exception $e) {
        return response($e->getMessage(), 500);
    }

    $time_end = microtime(true);
    $execution_time = ($time_end - $time_start);

    return view('search', compact('results', 'execution_time'));
}
关键注意事项
  • 路径一致性:客户端必须使用与服务端完全相同的socket路径,推荐用base_path('tmp.sock')获取项目根目录下的socket文件,避免相对路径错误。
  • 协议匹配:服务端是HTTP协议,客户端必须发送符合HTTP规范的请求,不能直接传输原始数据。
  • 环境适配:Web请求环境优先选择Guzzle同步方案,避免阻塞Web进程;CLI脚本可使用Workerman异步方案。

内容的提问来源于stack exchange,提问作者Jake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 20:01:13