用微信小程序请求workerman的wss 报错,请各位大神指导一下

mwz747512353

问题描述

我这边是用thinkphp6的workerman请求openai接口,用微信小程序调用wss地址,经常会出现*4556 recv() failed (104: Connection reset by peer) while proxying upgraded connection,报错

程序代码

public function onMessage($connection, $data)
    {
        ob_start(null,4096);
        $open_ai_key = "xxxx";//你的key\
        $show = json_decode($data,true);
        if(!empty($show['type'])){
            if (ob_get_length() > 0) {
                ob_flush();
                flush();
            } else if (ob_get_level() > 0) {
                ob_end_clean();
            }
            return;
        }
        if(!$this->is_vip_expired($show['uid'])){
            $vipNum = Member::where('id',$show['uid'])->value('vipNum');
            if($vipNum==0){
                $vipMsg = '您好,您的可用次数为<span style="color:red">0</span>,需要继续使用,请开通会员。';
                //更新模型时间
                Dialog::where('id',$show['dialogId'])->update(['updateTime'=>date('Y-m-d H:i:s')]);
                $connection->send($vipMsg);
                if (ob_get_length() > 0) {
                    ob_flush();
                    flush();
                } else if (ob_get_level() > 0) {
                    ob_end_clean();
                }
                return;
            }else{
                Member::where('id',$show['uid'])->dec('vipNum')->update();;
            }
        }
        $messageData=[];
        if($show['message']==''){
            $classDataID=Dialog::where('id',$show['dialogId'])->value('classDataId');
            $classData =FzhelpClassPresets::where('classDataId',$classDataID)->select();
            $show['msg']=FzhelpClassData::where('classDataId',$classDataID)->value('desc');
            foreach($classData as $k=>$v){
                $messageData[$k]['role']=$v['type'];
                $messageData[$k]['content']=$v['content'];
            }
        }else{
            $messageDialog = DialogData::where('dialogId',$show['dialogId'])->limit(getFzhelpConfig('histNews'))->order('createTime desc')->select();
            $strlen=0;
            $count = count($messageDialog);
            foreach($messageDialog as $k=>$v){
                if($count-1!==$k){
                    $messageData[$k]['role']=$v['type']==2?'assistant':'user';
                    $messageData[$k]['content']=$v['content'];
                    $strlen+=strlen($v['content']);
                }
            }
            $messageNewData[]=[
                "role" => "user",
                "content" => $show['message']
            ];
            $messageData = array_merge($messageData, $messageNewData);
        }
        $opts = [
            "stream" => true,
            'model' => getFzhelpConfig('apiModel'),
            'messages' => $messageData,
            'temperature' => (float)getFzhelpConfig('temperature'),
            'max_tokens' => (int)getFzhelpConfig('maxTokens'),
            'frequency_penalty' => 0,
            'presence_penalty' => (float) getFzhelpConfig('presence'),
            'user'=>$show['openId']
        ];
        $headers  = [
            'Accept: application/json',
            'Content-Type: application/json',
            'Authorization: Bearer ' . $open_ai_key
        ];
        //返回数据
        $response = '';
        $imperfect='';
        $callback = function ($ch, $data) use ($connection,$show,&$response,&$imperfect){
            if($show['message']==''){
//                添加机器人消息入库
                DialogData::create([
                    'dialogId'=>$show['dialogId'],
                    'type'=>2,
                    'content'=>$show['msg'],
                    'zan'=>0,
                    'cai'=>0,
                ]);
                //更新模型时间
                Dialog::where('id',$show['dialogId'])->update(['updateTime'=>date('Y-m-d H:i:s')]);
                $connection->send($show['msg']);
                if (ob_get_length() > 0) {
                    ob_flush();
                    flush();
                } else if (ob_get_level() > 0) {
                    ob_end_clean();
                }
                return $show['msg'];
            }
            $dataLength = strlen($data);
//有可能会返回不完整的数据
            if($imperfect){
                $data = $imperfect . $data;
                $imperfect = '';
            }else {
                if (substr($data, -1) !== "\n") {
                    $imperfect = $data;
                    return $dataLength;
                }
            }
            $pword = $this->parseData($data);
            if(strpos($pword, 'data: [DONE]') !== false){
                $un_word = str_replace("data: [DONE]","",$pword);
                $response .= $un_word;
                if (!empty($response)) {
                    $addDialog=DialogData::create([
                        'dialogId'=>$show['dialogId'],
                        'type'=>2,
                        'content'=>$response,
                        'zan'=>0,
                        'cai'=>0,
                    ]);
                    //更新模型时间
                    Dialog::where('id',$show['dialogId'])->update(['updateTime'=>date('Y-m-d H:i:s')]);
                    $connection->send('endId_miaowenzhen:['.$addDialog->id.']');
                    ob_flush();flush();
                    $response = '';
                }
                $connection->send($pword);
                ob_flush();flush();
            }else{
                $response .= $pword;
                $connection->send($pword);
                ob_flush();flush();
            }
            return strlen($data);
        };
//        header('Content-Type: text/event-stream');
//        header('Cache-Control: no-cache');
//        header('Connection: keep-alive');
//        header('X-Accel-Buffering: no');
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_URL, getFzhelpConfig('apiUrl'));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_BUFFERSIZE,8192);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($opts));
        curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback);
        curl_exec($ch);
    }

报错信息

*4556 recv() failed (104: Connection reset by peer) while proxying upgraded connection, client: *.*.*.*, server: xxx.xxx.com, request: "GET /wss HTTP/1.1", upstream: "http://127.0.0.1:2345/wss", host: "xxx.xxx.com", referrer: "https://servicewechat.com/xxxxxxx/devtools/page-frame.html"

截图报错信息里报错文件相关代码

截图

操作系统及workerman/webman等框架组件具体版本

Debian GNU/Linux 11 x86_64
nginx:1.22.1
php:8.1.13
thinkphp:6.1
workerman:3.5.34

457 2 1
2个回答

walkor

Connection reset by peer 一般是workerman进程退出了,可能是业务出了致命错误导致,需要查看日志,也可能是workerman进行了restart reload等操作

  • mwz747512353 2023-07-21

    您好,我看了日志workerman没有任何报错,但是第二次重连,他有可能就正常了

小W

while proxying upgraded connection

貌似是nginx代理的问题,链接断开了吧

  • mwz747512353 2023-07-21

    是断掉了,应该就是nginx的问题,然后网上的办法都看了看,php和php-fpm的一些配置都改了,但该出现这问题的时候,貌似还是出现

  • 小W 2023-07-21

    (排除wm代码问题的话):

    1. 你的启动方式;
    2. nginx 的wss配置
    3. nginx日志看看有没有报错
  • mwz747512353 2023-07-21

    nginx报错就是上面的那个报错,启动方式就是php think worker:server start

🔝