Giao thức WebSocket

Hiện tại phiên bản giao thức WebSocket của Workerman là 13.

Giao thức WebSocket là một giao thức mới trong HTML5. Nó cho phép giao tiếp hai chiều giữa trình duyệt và máy chủ.

Mối quan hệ giữa WebSocket và TCP

WebSocket giống như HTTP, nó là một giao thức tầng ứng dụng, và đều dựa trên truyền tải TCP, WebSocket không có mối liên hệ lớn với Socket, cũng không thể đồng nhất chúng.

Quy trình bắt tay giao thức WebSocket

Giao thức WebSocket có một quy trình bắt tay, trong quá trình bắt tay, trình duyệt và máy chủ giao tiếp bằng giao thức HTTP, trong Workerman có thể can thiệp vào quy trình bắt tay như sau.

Khi workerman <= 4.1

<?php
require_once __DIR__ . '/vendor/autoload.php';

use Workerman\Connection\TcpConnection;
use Workerman\Worker;

$ws = new Worker('websocket://0.0.0.0:8181');
$ws->onConnect = function($connection)
{
    $connection->onWebSocketConnect = function($connection , $httpBuffer)
    {
        // Có thể kiểm tra nguồn kết nối ở đây, nếu không hợp lệ thì đóng kết nối
        // $_SERVER['HTTP_ORIGIN'] xác định trang web nào đã khởi tạo kết nối websocket
        if($_SERVER['HTTP_ORIGIN'] != 'https://www.workerman.net')
        {
            $connection->close();
        }
        // Trong onWebSocketConnect, $_GET $_SERVER có thể sử dụng
        // var_dump($_GET, $_SERVER);
    };
};
Worker::runAll();

Khi workerman >= 5.0

<?php
require_once __DIR__ . '/vendor/autoload.php';

use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Worker;

$worker = new Worker('websocket://0.0.0.0:12345');
$worker->onWebSocketConnect = function (TcpConnection $connection, Request $request) {
    if ($request->header('origin') != 'https://www.workerman.net') {
        $connection->close();
    }
    var_dump($request->get());
    var_dump($request->header());
};
Worker::runAll();

Truyền dữ liệu nhị phân qua giao thức WebSocket

Giao thức websocket mặc định chỉ có thể truyền tải văn bản utf8, nếu muốn truyền tải dữ liệu nhị phân, vui lòng xem phần dưới đây.

Trong giao thức websocket, một cờ được sử dụng trong tiêu đề để đánh dấu dữ liệu truyền tải là nhị phân hay văn bản utf8, trình duyệt sẽ xác nhận xem cờ và loại nội dung truyền tải có tương thích hay không, nếu không, kết nối sẽ bị ngắt.

Vì vậy, khi máy chủ gửi dữ liệu, cần phải thiết lập cờ này dựa trên loại dữ liệu truyền tải, trong Workerman, nếu là văn bản utf8 thông thường, thì cần thiết lập (mặc định là giá trị này, thường không cần thiết phải thiết lập thủ công)

use Workerman\Protocols\Websocket;
$connection->websocketType = Websocket::BINARY_TYPE_BLOB;

Nếu là dữ liệu nhị phân, thì cần thiết lập

use Workerman\Protocols\Websocket;
$connection->websocketType = Websocket::BINARY_TYPE_ARRAYBUFFER;

Lưu ý: Nếu không thiết lập $connection->websocketType, thì mặc định $connection->websocketType sẽ là BINARY_TYPE_BLOB (tức là loại văn bản utf8). Nói chung, dữ liệu thường được truyền tải là văn bản utf8, ví dụ như dữ liệu json, vì vậy không cần thiết phải thiết lập thủ công $connection->websocketType. Chỉ khi truyền tải dữ liệu nhị phân (ví dụ như dữ liệu hình ảnh, dữ liệu protobuffer, v.v.) mới cần thiết lập thuộc tính này thành BINARY_TYPE_ARRAYBUFFER.

Sử dụng workerman làm client WebSocket

Có thể sử dụng AsyncTcpConnection lớp kết hợp với giao thức ws để cho workerman hoạt động như một client websocket kết nối tới máy chủ websocket từ xa, hoàn thành việc truyền thông theo thời gian thực hai chiều.