"\r\n\r\n"" ; enfin, utilisez simplement la méthode de traitement du protocole EOF pour résoudre le problème du json incomplet."/> "\r\n\r\n"" ; enfin, utilisez simplement la méthode de traitement du protocole EOF pour résoudre le problème du json incomplet.">

Maison  >  Article  >  cadre php  >  Que faire si swoole json est incomplet

Que faire si swoole json est incomplet

藏色散人
藏色散人original
2020-04-09 10:16:492423parcourir

Que faire si swoole json est incomplet

Que dois-je faire si le swoole json est incomplet ?

swooleSolution au problème d'intégrité de l'envoi et de la réception de données entre le client et le serveur

1. Dans l'exemple suivant, après avoir démarré le service swoole, il écoute le port 9501 et reçoit les données de Les données envoyées par le client sont renvoyées inchangées.

class Server
{
    private $serv;
    public function __construct() {
        $this->serv = new swoole_server("127.0.0.1", 9501);
        $this->serv->set(array(
            'worker_num'     => 4,   //一般设置为服务器CPU数的1-4倍
            'daemonize'      => 1,  //以守护进程执行
            'max_request'     => 2000,
            'dispatch_mode'    => 2,//进程数据包分配模式 1平均分配,2按FD取摸固定分配,3抢占式分配
            'task_worker_num'   => 8,  //task进程的数量
            "task_ipc_mode "   => 3 ,  //使用消息队列通信,并设置为争抢模式
            "log_file"      => "./log/taskqueueu.log" ,//日志
        ));
        $this->serv->on('Receive', array($this,'onReceive'));//接收到数据时回调此函数
        $this->serv->start();
    }
    public function onReceive(swoole_server $serv, $fd, $from_id, $data ) {
                $serv->send($fd, $data);
                        usleep(500); //不加延时的话,经常两条数据被合并成一条返回了。
                        $serv->close($fd);
    }   
    public function onClose(swoole_server $serv, $fd) {
                $serv->send($fd, 'CLOSED');
    }   
}

Démarrez le serveur directement avec le nouveau serveur.

2. Démarrez le client swoole, envoyez les données au serveur et recevez le retour.

$client = new swoole_client(SWOOLE_SOCK_TCP);
if (!$client->connect('127.0.0.1', 9501, -1))
{
    exit("connect failed. Error: {$client->errCode}\n");
}
$data=[
        'type'=>1, 
        'data'=>array(
                'PlatformCode'=>'...........很长的数据.',
            )
   ];
$sender=$client->send(json_encode($data)."\r\n\r\n");
while($result = $client->recv()){
    if($result=='CLOSED'){
            echo "任务结束。byebye~\r\n";
            break;
    }else{
      echo $result;
  }
}
$client->close();

Lors de l'envoi d'un paquet de données relativement volumineux, vous constaterez que le paquet json reçu est incomplet. Cela peut être résolu en utilisant la méthode de traitement du protocole EOF, telle que le réglage sur le serveur :

    $serv->set(
        array('open_eof_split' => TRUE, 'package_eof' => "\r\n\r\n")
    );
<.>De cette façon, 'rnrn' devient le caractère de fin du protocole EOF.

Lors de l'envoi d'un paquet de données, ajoutez 'rnrn' à la fin du paquet. Lorsque ce caractère est rencontré lors de la rencontre des données d'interface, on considère que les données ont été reçues, garantissant ainsi l'intégrité de. les données.

Remarque : le caractère 'rnrn' ne peut pas apparaître dans le paquet de données, sinon une erreur de sous-paquet se produira.

Le serveur de Swoole et le client asynchrone traitent tous deux les paquets de données dans la fonction de rappel onReceive Lorsque le traitement du protocole est défini, l'événement onReceive ne sera déclenché que lorsqu'un paquet de données complet est reçu.

D'une autre manière, vous pouvez également prédéfinir la longueur du paquet à envoyer, par exemple :

$server->set(array(
        &#39;open_length_check&#39; => true,
        &#39;package_max_length&#39; => 81920,
        &#39;package_length_type&#39; => &#39;n&#39;, //see php pack()
        &#39;package_length_offset&#39; => 0,
        &#39;package_body_offset&#39; => 2,
));

Vous pouvez fixer la longueur du paquet pour garantir l'intégrité des données. Le commentaire officiel est le suivant :

Le protocole d'en-tête fixe est très courant et peut souvent être vu dans les programmes serveur BAT. La particularité de ce protocole est qu'un paquet de données est toujours constitué de 2 parties : en-tête + corps. L'en-tête du paquet comporte un champ qui spécifie la longueur du corps du paquet ou du paquet entier. La longueur est généralement représentée par un entier de 2 octets/4 octets. Une fois que le serveur a reçu l'en-tête du paquet, il peut contrôler avec précision la quantité de données supplémentaires dont il a besoin en fonction de la valeur de longueur pour obtenir un paquet de données complet. La configuration de Swoole peut très bien prendre en charge ce protocole et peut définir de manière flexible quatre paramètres pour faire face à toutes les situations.

Le serveur de Swoole et le client asynchrone traitent tous deux les paquets de données dans la fonction de rappel onReceive Lorsque le traitement du protocole est défini, l'événement onReceive ne sera déclenché que lorsqu'un paquet de données complet est reçu. Une fois que le client de synchronisation a configuré le traitement du protocole, l'appel de $client->recv() ne nécessite plus de transmettre la longueur. La fonction recv revient après avoir reçu le paquet complet ou une erreur se produit.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn