Investigación sobre cuestiones de conexión del cliente de almacenamiento de trabajadores y comunicación entre procesos.

Investigación sobre cuestiones de conexión del cliente de almacenamiento de trabajadores y comunicación entre procesos.

1. En primer lugar, este wiki se basa en los cambios en el código del servidor según la estructura del proyecto de la empresa "[[Indoor Navigation Solution]]".

2. En segundo lugar, nací en ue4 y c++ y nunca entendí php. Antes de aprender sobre Workman, mi conocimiento de PHP era solo usar PHP para conectarme a la base de datos y luego devolver los datos a C++ para usarlos a través de get. No entiendo la sintaxis de PHP, las especificaciones del código, etc. Entonces, si hay algún problema, corríjame.

1: Cuando el trabajador es un proceso único, el problema de compartir variables de matriz

Requisitos : Cuando procesamos conexiones de clientes, debemos dividir los enlaces de clientes en dos categorías: WeChat y Web, y al mismo tiempo corresponden uno a uno, es decir, un terminal WeChat debe corresponder a un terminal web.
Idea : Nuestra idea es crear dos matrices ($WX=array(); $Web=array()). Almacene todas las conexiones de WeChat en $ WX y almacene todas las conexiones web en Web.
Problema encontrado : estas dos matrices no se almacenan todo el tiempo. Cuando llega la conexión, está claramente almacenada en la matriz, pero cuando llega el mensaje, ambas matrices están vacías.

Solución: ① Defina estas dos matrices en la clase de trabajador. ②: Agregue "global $ws_worker;" a la primera oración de cada función en su propia clase en ejecución para hacer que nuestro $ws_worker sea global. (¡Usando la sintaxis de C++, es simplemente difícil entender esta forma de escribir!)

//在库文件worker.php里面添加、声明两个数组
//定义两个数组用于存储所有的WX连接,所有的Web连接
    public $WX=array();
    public $Web=array();
//在我们自己写的run.php里面
//每个函数里面申明我们的全局worker
$ws_worker->onMessage = function($connection, $data)
{
   global $ws_worker;
   ......       
}
      Después de procesar de esta manera, podemos guardar muy bien estos enlaces, de modo que cuando llegue un mensaje del cliente wx, podamos encontrar la Web correspondiente para reenviar el mensaje. Pero todavía está limitado a $ws_worker->count = 1; al iniciar un proceso.

2: Cuando hay múltiples procesos de trabajo, comunicación mutua entre procesos.

Requisitos : cuando usamos trabajadores como servidores, cuando el número de conexiones es relativamente pequeño, podemos usar $ws_worker->count = 1; se puede manejar por completo. Pero si encuentra un proyecto con una cantidad relativamente grande de conexiones, entonces $ws_worker->count = 4; aún es necesario.
Idea : utilice el componente Channel basado en trabajadores para comunicarse entre subprocesos. El canal son dos archivos php Client.php y Server.php.
La solución está disponible después de la descarga : ①: Registre el evento en la función "onWorkerStart" cuando se inicie el proceso de trabajo (lo entiendo como registro). ②Cuando se requiere comunicación entre subprocesos, llamamos "\Channel\Client::publish('Findandclose', $event_data);" para el evento correspondiente registrado.   
// 每个worker进程启动时(这个函数是进程间通讯,事件注册用)
$ws_worker->onWorkerStart = function($ws_worker)
{
    //需要跨线程做的事都写在这里
    // Channel客户端连接到Channel服务端
    Channel\Client::connect('127.0.0.1', 2206);
    // 注册"Findandforward"事件,用于消息转发时当前进程找不到对应连接时调用
    Channel\Client::on('Findandforward', function($event_data)use($ws_worker){
      if($event_data->type == 'Message')
      {
        if($event_data->from == 'WX')
        {
               foreach ($ws_worker->Web as $everyweb) 
               {
                 if($event_data->openid == $everyweb['openid'])
                 {
                   $everyweb['connect']->send($event_data->data);
                   break;
                 }
		       }
        }
      }
    });
    // 注册"Findandclose"事件,用于连接断开时当前进程找不到对应连接
      Channel\Client::on('Findandclose', function($event_data)use($ws_worker){
      if($event_data['Who_closed']== 'WX_closed')
      {
          foreach( $ws_worker->Web as $key => $value ) {
            if($value['openid'] ==$event_data['openid'])
            {
              $ws_worker->Web[$key]['connect']->close();
              array_splice($ws_worker->Web,$key,1);//重置数组
              var_dump($ws_worker->Web);
              savelog("在其它进程找到了需要关闭的Web连接"."  ".$event_data['openid']);
              break;
            }
          }
      }
      if($event_data['Who_closed']== 'Web_closed')
      {
          foreach( $ws_worker->WX as $key => $value ) {
            if($value['openid'] ==$event_data['openid'])
            {
              $ws_worker->WX[$key]['connect']->close();
              array_splice($ws_worker->WX,$key,1);//重置数组
              var_dump($ws_worker->WX);
              savelog("在其它进程找到了需要关闭的WX连接"."  ".$event_data['openid']);
              break;
            }
          }
      }  
    });
};
//调用我们的跨线程事件
      if($jsondata->from == 'WX')
      {          
          savelog("WX is sen Message the WX id is"."   ".$jsondata->openid);
           //循环$Web匹配本次消息的openid对应有就将小程序的消息转发给web
            $isfind_theweb=false;//定义一个Bool变量,判断在当前线程是否找到对应的连接
            foreach ($ws_worker->Web as $everyweb) {
  			if($jsondata->openid == $everyweb['openid'])
            {
              $isfind_theweb=true;//当前线程找到了对应连接
                $everyweb['connect']->send($jsondata->data);
                break;
            }
		}
        if(!$isfind_theweb)//如果在这个进程没有找到对应的web,我们发送全局事件
        {
          savelog("当前进程未找到匹配连接");
          $event_data = $jsondata;
          // 向所有worker进程发布Findandforward事件
          \Channel\Client::publish('Findandforward', $event_data);//Findandforward是我们要调用的事件名,$event_data是我们要传递的参数
        }   
      }

 Resumir

      Una vez que se usa Workerman, puede servir a muchos de nuestros proyectos. Más adelante, el lado del servidor básicamente utilizará la comunicación websocket, que sigue siendo algo muy útil. Por supuesto, esto es sólo una pequeña parte. Esta es la primera vez que entro en contacto con php. Si tiene mejores soluciones a los problemas anteriores, déjeme un mensaje. Respecto a otros aspectos, espero que puedas grabar y compartir más.

Supongo que te gusta

Origin blog.csdn.net/qq_22824481/article/details/80452125
Recomendado
Clasificación