walkor / phpsocket.io

A server side alternative implementation of socket.io in PHP based on workerman.
2.3k stars 508 forks source link

$socket is null #273

Open dly667 opened 2 years ago

dly667 commented 2 years ago
image

$socket is null

public function index()
  {
      ini_set('display_errors', 'on');
      error_reporting(E_ERROR | E_WARNING | E_PARSE);
      $port = Config::get('param.ws.inquire_post');
      $io = new SocketIO($port);
      $io->on('connection', function ($socket) use ($io) {
          // 初始化 websocket
          $socket->on('init', function ($msg) use ($io, $socket) {
              $this->init_connect($msg, $io, $socket);
          });

          $socket->on('server_message', function ($msg) use ($io, $socket) {
              $this->server_message($msg, $io, $socket);
          });
          $socket->on('logout', function ($msg) use ($io, $socket) {
              if (!isset($this->users[$socket->username])) {
                  $this->users[$socket->username] = 0;
              }

              --$this->users[$socket->username];
              if ($this->users[$socket->username] <= 0) {
                  echo $socket->username . ' logout' . PHP_EOL;
                  unset($this->users[$socket->username]);
                  --$this->usersNum;
                  $socket->leave($socket->username);

                  echo date('Y-m-d H:i:s') . " {$socket->token} logout" . PHP_EOL;
              }
              $socket->emit('logout', 'logout success');
          });
          $socket->on('error', function ($err) use ($io, $socket) {
              // 错误日志
              try{
                  $content = $err->getTraceAsString();
                  $content .= "\n ---------------------------------------------".date('Y-m-d h:i:s', time()).'------'; ;
                  $my_path = Env::get('root_path').'logs/socketio/erp_ws';
                  file_put_contents($my_path, $content, FILE_APPEND);
              } catch (Exception $e){
                  var_dump($e->getTraceAsString());
              }
          });

          // 监听客户端连接成功发送数据
          $socket->on('success', function ($msg) use ($io, $socket) {

              echo date('Y-m-d H:i:s') . " join" . PHP_EOL;
          });

          // 关闭页面/离开聊天室
          $socket->on('disconnect', function () use ($socket) {
              if (!isset($this->users[$socket->username])) {
                  $this->users[$socket->username] = 0;
              }
              --$this->users[$socket->username];
              if ($this->users[$socket->username] <= 0) {
                  unset($this->users[$socket->username]);
                  --$this->usersNum;
                  $socket->leave($socket->username);
                  $res = [
                      'username' => $socket->username,
                      'usersNum' => $this->usersNum,
                      'currentUsers' => $this->users,
                      'type' => 'left',
                  ];

                  if (!$socket->token){
                      echo date('Y-m-d H:i:s') . " 未初始化的连接 关闭连接leave" . PHP_EOL;
                  }else{
                      $token = $socket->token;
                      echo date('Y-m-d H:i:s') . " {$socket->$token}, {$socket->token} leave" . PHP_EOL;
                  }
              }
          });

      });

      // 当$io启动后监听一个http端口,通过这个端口可以给任意user或者所有user推送数据
      $io->on('workerStart', function ($worker) use ($io) {
          // 监听一个http端口
          $api_url = Config::get('param.ws.apiHost');
          $inner_http_worker = new Worker($api_url);
          $inner_http_worker->onError = function($connection, $code, $msg)
          {
              echo "error $code $msg\n";
          };
          // 当http客户端发来数据时触发
          $inner_http_worker->onMessage = function ($http_connection, $data) use ($io) {
              $io->emit('message', 'messg251');

              // 返回结果
              return $http_connection->send('1');
          };
          // 执行监听
          $inner_http_worker->listen();
      });
      Worker::runAll();
  }
private function init_connect_handle($msg, $io, $socket){
        // 验证token
        $token = $msg['token']??'';
        if ($token) {
            if (empty($socket->$token)) {
                $socket->emit('message', [
                    'errcode' => 0,
                    'msg' => 'token' . $token,
                    'datas' => $token
                ]);
                $user_id = validation_token($token, true); // 不需要直接调用write_json
                if (!$user_id){
                    $socket->emit('message', [
                        'errcode' => 1011,
                        'msg' => 'redis连接失败',
                        'datas' => $user_id
                    ]);
                    return ;
                }
                $socket->emit('message', [
                    'errcode' => 0,
                    'msg' => '$user_id' . $user_id,
                    'datas' => $user_id
                ]);

                if (!empty($user_id)) {
                    // 将当前客户端加入以他的用户名定义的group
                    $socket->join($user_id);
                    // 当前连接的上下文变量
                    $socket->$token = $user_id;
                    $socket->token = $token;
                    $socket->user_id = $user_id;
                    $socket->emit('message', [
                        'errcode' => 0,
                        'msg' => '初始化成功',
                        'datas' => []
                    ]);
                } else {
                    $socket->emit('message', [
                        'errcode' => 0,
                        'msg' => '错误的token',
                        'datas' => []
                    ]);
                }
            }else{
                $socket->emit('message', [
                    'errcode' => 0,
                    'msg' => '该连接的token已经初始化',
                    'datas' => []
                ]);
            }
        }else{
            $socket->emit('message', [
                'errcode' => 0,
                'msg' => 'token不能为空',
                'datas' => []
            ]);
        }
    }
    private function init_connect($msg, $io, $socket){
        if (empty($socket)){
            return ;
        }
        try{
            $this->init_connect_handle($msg, $io, $socket);
        }catch (Exception $e){
            echo '打印错误信息';
            dump($e->getTraceAsString());
            echo '打印错误信息结束';
        }

    }
walkor commented 2 years ago

感觉是连接已经关闭后执行了join操作导致。 https://github.com/walkor/phpsocket.io/blob/master/src/Socket.php

     public function join($room)
     {
        if(isset($this->rooms[$room])) return $this;
        $this->adapter->add($this->id, $room);
        $this->rooms[$room] = $room;
        return $this;
    }

改成

     public function join($room)
     {
        if (!$this->connected) return $this;
        if(isset($this->rooms[$room])) return $this;
        $this->adapter->add($this->id, $room);
        $this->rooms[$room] = $room;
        return $this;
    }

试下看下还是否报错

dly667 commented 2 years ago
image

错误出现了很多次,join这里的错误。 emit 执行没有错误。

walkor commented 2 years ago

https://github.com/walkor/phpsocket.io/blob/master/src/Socket.php 里 join方法加一句if (!$this->connected) return $this;

dly667 commented 2 years ago

好的,谢谢。