服务器发送的事件未连接

时间:2019-08-24 13:39:53

标签: javascript php jquery

我有用于网聊脚本的这段代码。我正在使用RedBean PHP来管理数据库操作,并使用ajax plus事件源API来管理与消息相关的发送和接收事件。我注意到SSE状态代码将保持为0,并且数据库中不会显示任何消息。我该如何解决这个问题?

JS

$('#sendBtn').click(function(e){
        e.preventDefault();
        if(typeof token != 'undefined'){
          var peerUrl = 'https://localhost/chat/api/v1/'+token;
          var data = {'token': token , 'user': username , 'message': $('input[name="message"]').val()}
          $.post(peerUrl, data).done(function(response){
            console.log(response);
          });
          $('input[name="message"]').val(null);
        }
      });

      // Receiving message

              msg = new EventSource('https://localhost/chat/api/v1/'+token);
              console.log(msg.readyState);

              msg.addEventListener('message', function(e){
                console.log(e);
              });

PHP

require_once __DIR__.'/config.inc';

require_once AUTOLOADER;

use FastRoute\RouteCollector;
use FastRoute\simpleDispatcher;
use FastRoute\Dispatcher;
use RedBeanPHP\R;

$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r){
    // test route
    $r->addRoute('GET', '/chat/', 'Controller@index');

    $r->addGroup('/lchat/api/v1', function(FastRoute\RouteCollector $r){
      $r->addRoute('GET', '/{id:\w+}', 'Controller@receive');
      $r->addRoute('POST', '/{id:\w+}', 'Controller@send');
    });

    $r->addRoute('GET', '/chat/inbox/', 'Controller@openChannel');
    $r->addRoute('GET', '/chat/inbox/r/{id:\w+}', 'Controller@showInbox');
});

// Fetch method and URI from somewhere
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];

// Strip query string (?foo=bar) and decode URI
if (false !== $pos = strpos($uri, '?')) {
    $uri = substr($uri, 0, $pos);
}
$uri = rawurldecode($uri);

$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0]) {
    case FastRoute\Dispatcher::NOT_FOUND:
        // ... 404 Not Found
        break;
    case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
        $allowedMethods = $routeInfo[1];
        // ... 405 Method Not Allowed
        break;
    case FastRoute\Dispatcher::FOUND:
        $handler = $routeInfo[1];
        $vars = $routeInfo[2];

        list($class, $method) = explode("@", $handler, 2);
        call_user_func_array([new $class, $method], $vars);
        break;
}


class Controller {

  public function __construct()
  {
    $this->dbh = R::setup( 'mysql:host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASS );
    $this->templates = new League\Plates\Engine(TEMPLATE_PATH);
    $this->templates->loadExtension(new League\Plates\Extension\Asset(TEMPLATE_ASSETS_PATH.'/'));
  }

  public function index()
  {
    echo $this->templates->render('home');
  }

  public function openChannel()
  {
    $room_id = bin2hex(openssl_random_pseudo_bytes(4));
    header('Location: r/'.$room_id);
  }

  public function showInbox($id)
  {

    echo $this->templates->render('inbox');
  }

  public function send()
  {
    if(isset($_POST) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){
      $message = R::dispense('messages');
      $message->roomCode = $_POST['token'];
      $message->from = $_POST['user'];
      $message->body = $_POST['message'];
      $message->timestamp = time();
      $message->read = false;
      $id = R::store($message);
    }
  }

  public function receive($id)
  {
    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache');

    ignore_user_abort(true);
    session_start();
    session_write_close();

    while(1){
      if( connection_aborted() ){
        exit;
      }
      else{

        $message = R::findOne( 'messages', 'room_code = ? AND read = ?', [ $id , 0 ] );
        if( !empty($message) ){

          $data = json_encode([
            'user' => $message->from,
            'msg' => $message->body,
            'time' => $message->timestamp
          ]);

          echo 'id: '. $message->id . PHP_EOL;
          echo 'event: message'. PHP_EOL;
          echo 'data: '. $data . PHP_EOL;
          echo PHP_EOL;

          $message->read = true;
          R::store($message);

          ob_flush();
          flush();
        }
        else{
           echo ': heartbeat'.PHP_EOL;
           ob_flush();
           flush();
        }
      }
      sleep(2);
    }

  }

}

0 个答案:

没有答案