当前位置:首页 > PHP

php 实现ws

2026-02-14 22:04:25PHP

PHP 实现 WebSocket 服务

WebSocket 是一种全双工通信协议,允许客户端和服务器之间进行实时数据交换。PHP 可以通过以下方式实现 WebSocket 服务。

使用 Ratchet 库

Ratchet 是一个流行的 PHP WebSocket 库,基于 ReactPHP 实现。

安装 Ratchet:

composer require cboden/ratchet

创建 WebSocket 服务器:

use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;

require dirname(__DIR__) . '/vendor/autoload.php';

$server = IoServer::factory(
    new HttpServer(
        new WsServer(
            new Chat()
        )
    ),
    8080
);

$server->run();

实现 Chat 类处理消息:

namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class Chat implements MessageComponentInterface {
    protected $clients;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn) {
        $this->clients->attach($conn);
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        foreach ($this->clients as $client) {
            if ($from !== $client) {
                $client->send($msg);
            }
        }
    }

    public function onClose(ConnectionInterface $conn) {
        $this->clients->detach($conn);
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        $conn->close();
    }
}

使用 Swoole 扩展

Swoole 是 PHP 的高性能网络通信引擎,内置 WebSocket 支持。

安装 Swoole:

pecl install swoole

创建 WebSocket 服务器:

$server = new Swoole\WebSocket\Server("0.0.0.0", 9501);

$server->on('open', function(Swoole\WebSocket\Server $server, $request) {
    echo "connection open: {$request->fd}\n";
});

$server->on('message', function(Swoole\WebSocket\Server $server, $frame) {
    foreach ($server->connections as $fd) {
        if ($fd !== $frame->fd) {
            $server->push($fd, $frame->data);
        }
    }
});

$server->on('close', function($server, $fd) {
    echo "connection close: {$fd}\n";
});

$server->start();

原生 PHP 实现

PHP 也可以使用原生 socket 函数实现 WebSocket,但需要手动处理握手协议。

创建 socket 服务器:

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8080);
socket_listen($socket);

while (true) {
    $client = socket_accept($socket);
    $headers = socket_read($client, 1024);

    if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $headers, $match)) {
        $key = base64_encode(sha1($match[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));
        $response = "HTTP/1.1 101 Switching Protocols\r\n";
        $response .= "Upgrade: websocket\r\n";
        $response .= "Connection: Upgrade\r\n";
        $response .= "Sec-WebSocket-Accept: $key\r\n\r\n";
        socket_write($client, $response, strlen($response));
    }

    // 消息处理逻辑...
}

客户端连接示例

HTML/JavaScript 客户端连接代码:

php 实现ws

<script>
const socket = new WebSocket('ws://localhost:8080');
socket.onopen = function(e) {
    console.log('Connection established');
};
socket.onmessage = function(event) {
    console.log('Data received: ' + event.data);
};
socket.onclose = function(event) {
    console.log('Connection closed');
};
</script>

注意事项

  • Ratchet 适合中小型应用,安装简单但性能有限
  • Swoole 性能优异,适合高并发场景,但需要安装扩展
  • 原生实现灵活性高,但开发复杂度大,需要处理协议细节
  • 生产环境建议使用 Nginx 反向代理 WebSocket 连接
  • 注意实现心跳机制保持连接活跃
  • 考虑添加 SSL/TLS 支持(wss://)增强安全性

以上方法提供了不同复杂度和性能级别的 PHP WebSocket 实现方案,可根据项目需求选择合适的实现方式。

标签: phpws
分享给朋友:

相关文章

php 实现自动收货

php 实现自动收货

PHP 实现自动收货功能 自动收货功能通常用于电商系统,在订单超过一定时间未手动确认收货时自动完成订单。以下是实现方法: 数据库设计 需要订单表包含以下关键字段: CREATE TABLE…

php实现排序

php实现排序

PHP 数组排序方法 PHP 提供了多种内置函数用于数组排序,适用于不同的排序需求。以下是常见的排序方法: 按值升序排序 sort() 函数对数组按值升序排序,重置键名(索引数组适用): $num…

php 实现秒杀

php 实现秒杀

PHP 实现秒杀的关键技术 秒杀系统需要解决高并发、超卖、性能瓶颈等问题。以下是实现秒杀的核心方案: 使用 Redis 预减库存 将商品库存提前加载到 Redis 中,通过原子操作保证库存准确性:…

php实现伪静态

php实现伪静态

PHP 实现伪静态的方法 伪静态(URL Rewrite)是一种将动态URL转换为看似静态URL的技术,提升SEO友好性和用户体验。以下是几种常见的实现方式: 使用 Apache 的 mod_rew…

php实现短信验证

php实现短信验证

PHP实现短信验证的步骤 选择合适的短信服务提供商 国内常见的短信服务提供商包括阿里云短信、腾讯云短信、云片等。注册账号并获取API密钥和签名模板是第一步。这些平台通常提供详细的开发文档和SDK。…

php session 实现购物车

php session 实现购物车

PHP Session 实现购物车的方法 初始化 Session 在 PHP 脚本的最开始调用 session_start() 函数,确保会话已启用。这通常在页面的顶部完成。 session_sta…