Thư viện máy khách websocket php

Các hướng dẫn trước đây đều rất thú vị, nhưng trọng tâm của chúng là tạo ra một ứng dụng tồn tại lâu dài, nơi người dùng tương tác với nhau hoàn toàn qua WebSockets mà không cần kiên trì. Đó là rất nhiều công việc để kết hợp vào một trang web đã có sẵn. Mã sẽ cần được chuyển ra khỏi kho lưu trữ của bạn và vào một ứng dụng Ratchet mới. Một giai đoạn thử nghiệm hoàn toàn mới sẽ cần phải diễn ra để đảm bảo các trang chức năng trước đây vẫn hoạt động

Mục tiêu

Khi người dùng, có thể là chính bạn trong quản trị viên của bạn hoặc người dùng đăng nhận xét trên blog của bạn, thực hiện POST thông qua gửi biểu mẫu hoặc AJAX, chúng tôi muốn thay đổi đó ngay lập tức được gửi tới tất cả khách truy cập khác trên trang đó. Chúng tôi sẽ thêm các bản cập nhật theo thời gian thực vào trang web của chúng tôi mà không làm gián đoạn cơ sở mã của bạn hoặc ảnh hưởng đến sự ổn định hiện tại của nó

Đối với hướng dẫn này, chúng tôi sẽ giả vờ (đọc. thiếu mã soạn sẵn) bạn đang xuất bản một bài viết blog trên trang web của mình và khách truy cập sẽ thấy câu chuyện bật lên ngay sau khi bạn xuất bản nó

Kiến trúc mạng

  1. Máy khách đưa ra yêu cầu và nhận phản hồi từ máy chủ web và hiển thị trang. Sau đó, nó thiết lập kết nối WebSocket mở (máy khách 2 và 3 làm điều tương tự)

  2. Máy khách 1 thực hiện POST lại, thông qua gửi biểu mẫu hoặc AJAX, tới máy chủ web. (Lưu ý kết nối WebSocket vẫn mở)

  3. Trong khi máy chủ đang xử lý yêu cầu POST (lưu vào cơ sở dữ liệu, v.v.), nó sẽ gửi một tin nhắn trực tiếp đến ngăn xếp WebSocket bằng phương thức vận chuyển ZeroMQ

  4. Ngăn xếp WebSocket xử lý thông báo ZeroMQ và gửi nó đến các máy khách thích hợp thông qua các kết nối WebSocket mở. Các trình duyệt web xử lý tin nhắn đến và cập nhật trang web bằng Javascript tương ứng

Quy trình làm việc này không phô trương và dễ dàng đưa vào các trang web hiện có. Những thay đổi duy nhất đối với trang web là thêm một chút ZeroMQ vào máy chủ và tệp Javascript trên máy khách để xử lý thư đến từ máy chủ WebSocket

Yêu cầu

khôngMQ

Để giao tiếp với một tập lệnh đang chạy, nó cần phải lắng nghe trên một ổ cắm mở. Ứng dụng của chúng tôi sẽ lắng nghe cổng 8080 cho các kết nối WebSocket đến. nhưng làm thế nào nó cũng sẽ nhận được các bản cập nhật từ một tập lệnh PHP khác? . Chúng tôi có thể sử dụng các ổ cắm thô, giống như những cái mà Ratchet được xây dựng trên đó, nhưng ZeroMQ là một thư viện giúp tạo ra các ổ cắm dễ dàng hơn

ZeroMQ là một thư viện (libzmq) bạn sẽ cần cài đặt, cũng như một phần mở rộng PECL cho các liên kết PHP. Cài đặt dễ dàng và được cung cấp cho nhiều hệ điều hành trên trang web của họ

Phản ứng/ZMQ

Ratchet là một thư viện WebSocket được xây dựng trên thư viện socket có tên là React. React xử lý các kết nối và I/O thô cho Ratchet. Ngoài React, đi kèm với Ratchet, chúng tôi cần một thư viện khác là một phần của bộ React. Phản ứng/ZMQ. Thư viện này sẽ liên kết các ổ cắm ZeroMQ với lõi Lò phản ứng cho phép chúng tôi xử lý cả ổ cắm WebSockets và ZeroMQ. Để cài đặt, nhà soạn nhạc của bạn. tệp json sẽ trông như thế này

{
    "autoload": {
        "psr-4": {
            "MyApp\\": "src"
        }
    },
    "require": {
        "cboden/ratchet": "0.4.*",
        "react/zmq": "0.2.*|0.3.*"
    }
}

Bắt đầu mã hóa của bạn

Hãy đến với một số mã. Chúng tôi sẽ bắt đầu bằng cách khai thác ứng dụng lớp học của chúng tôi. Chúng tôi sẽ sử dụng WAMP để dễ sử dụng với mẫu Pub/Sub. Điều này sẽ cho phép khách hàng đăng ký nhận các bản cập nhật trên một trang cụ thể và chúng tôi sẽ chỉ đẩy các bản cập nhật tới những người đã đăng ký

callError($id, $topic, 'You are not allowed to make calls')->close();
    }
    public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {
        // In this application if clients send data it's because the user hacked around in console
        $conn->close();
    }
    public function onError(ConnectionInterface $conn, \Exception $e) {
    }
}

Lưu cái này vào /src/MyApp/Pusher. php. Chúng tôi chỉ thực hiện các phương thức cần thiết cho WAMP và đảm bảo rằng không ai cố gắng gửi dữ liệu, đóng kết nối nếu họ làm vậy. Chúng tôi đang tạo một ứng dụng đẩy và không chấp nhận bất kỳ tin nhắn đến nào từ WebSockets, tất cả những tin nhắn đó sẽ đến từ AJAX

Chỉnh sửa nội dung gửi blog của bạn

Tiếp theo, chúng tôi sẽ thêm một chút phép thuật ZeroMQ vào mã trang web hiện tại của bạn, nơi bạn xử lý một bài đăng blog mới. Mã ở đây có thể hơi cơ bản và cổ điển so với kiến ​​trúc nâng cao mà blog thực tế của bạn đang có, trên Drupal hoặc WordPress, nhưng chúng tôi đang tập trung vào các nguyên tắc cơ bản

 $_POST['category']
      , 'title'    => $_POST['title']
      , 'article'  => $_POST['article']
      , 'when'     => time()
    );

    $pdo->prepare("INSERT INTO blogs (title, article, category, published) VALUES (?, ?, ?, ?)")
        ->execute($entryData['title'], $entryData['article'], $entryData['category'], $entryData['when']);

    // This is our new stuff
    $context = new ZMQContext();
    $socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
    $socket->connect("tcp://localhost:5555");

    $socket->send(json_encode($entryData));

Sau khi chúng tôi đăng mục blog của bạn vào cơ sở dữ liệu, chúng tôi đã mở kết nối ZeroMQ tới máy chủ ổ cắm của chúng tôi và gửi một thông báo được tuần tự hóa với cùng thông tin. (Ghi chú. vui lòng vệ sinh đúng cách, đây chỉ là một ví dụ nhanh và bẩn)

Xử lý tin nhắn ZeroMQ

Hãy quay trở lại lớp sơ khai ứng dụng của chúng ta. Khi chúng tôi rời khỏi nó, nó chỉ xử lý các kết nối WebSocket. Như bạn đã thấy trong đoạn mã cuối cùng của chúng tôi, chúng tôi đã mở một kết nối tới máy chủ cục bộ trên cổng 5555 mà chúng tôi đã gửi dữ liệu tới. Chúng tôi sẽ thêm xử lý cho tin nhắn ZeroMQ đó cũng như gửi lại nó cho các máy khách WebSocket của chúng tôi

subscribedTopics[$topic->getId()] = $topic;
    }

    /**
     * @param string JSON'ified string we'll receive from ZeroMQ
     */
    public function onBlogEntry($entry) {
        $entryData = json_decode($entry, true);

        // If the lookup topic object isn't set there is no one to publish to
        if (!array_key_exists($entryData['category'], $this->subscribedTopics)) {
            return;
        }

        $topic = $this->subscribedTopics[$entryData['category']];

        // re-send the data to all the clients subscribed to that category
        $topic->broadcast($entryData);
    }

    /* The rest of our methods were as they were, omitted from docs to save space */
}

Liên kết tất cả lại với nhau Tạo tệp thực thi của chúng tôi

Cho đến nay, chúng tôi đã đề cập đến tất cả logic của việc gửi, nhận và xử lý tin nhắn. Bây giờ, chúng ta sẽ liên kết tất cả lại với nhau và tạo tập lệnh thực thi để quản lý mọi thứ. Chúng ta sẽ xây dựng ứng dụng Ratchet với các thành phần I/O, WebSockets, Wamp và ZeroMQ và chạy vòng lặp sự kiện

getSocket(ZMQ::SOCKET_PULL);
    $pull->bind('tcp://127.0.0.1:5555'); // Binding to 127.0.0.1 means the only client that can connect is itself
    $pull->on('message', array($pusher, 'onBlogEntry'));

    // Set up our WebSocket server for clients wanting real-time updates
    $webSock = new React\Socket\Server('0.0.0.0:8080', $loop); // Binding to 0.0.0.0 means remotes can connect
    $webServer = new Ratchet\Server\IoServer(
        new Ratchet\Http\HttpServer(
            new Ratchet\WebSocket\WsServer(
                new Ratchet\Wamp\WampServer(
                    $pusher
                )
            )
        ),
        $webSock
    );

    $loop->run();

Lưu mã dưới dạng /bin/push-server. php và chạy nó

$ php bin/push-server.php

Phía khách hàng Nhận cập nhật theo thời gian thực

Bây giờ, mã phía máy chủ của chúng tôi đã hoàn tất cũng như thiết lập và chạy, đã đến lúc tải các bài đăng theo thời gian thực đó. Cụ thể bạn làm gì với những cập nhật đó nằm ngoài phạm vi của tài liệu này, chúng tôi sẽ đưa những thông báo đó vào bảng điều khiển gỡ lỗi

Cuối cùng, hãy mở trang mà bạn đã đặt Javascript này bằng một cửa sổ trình duyệt và từ một trình duyệt khác, hãy đăng một mục blog lên "kittensCategory" và xem nhật ký bảng điều khiển của bạn ngay từ lần đầu tiên. Khi nó đang hoạt động, các bước tiếp theo của bạn là kết hợp dữ liệu nhận được vào một số tính năng thao tác DOM

Khi nó hoạt động cục bộ (giả sử localhost là môi trường phát triển của bạn), bạn có thể thay đổi các tham chiếu localhost và có thể là các liên kết với tên máy chủ/địa chỉ IP thích hợp của bạn