r-martins/php-websocket

PHP中简单WebSocket服务器和客户端实现。

v3.1.1 2022-02-01 23:59 UTC

README

无冗余的PHP WebSockets

PHP实现的简单WebSocket服务器。

安装

需求

  • PHP >= 7.4
  • ext-json
  • ext-sockets

安装步骤

使用composer安装包

composer require bloatless/php-websocket

使用

服务器

在您的机器上下载源代码后,您需要一些代码来真正将您的websocket服务器组合起来。以下是一个基本的示例

<?php

// require necessary files here

// create new server instance
$server = new \Bloatless\WebSocket\Server('127.0.0.1', 8000, '/tmp/phpwss.sock');

// server settings
$server->setMaxClients(100);
$server->setCheckOrigin(false);
$server->setAllowedOrigin('example.com');
$server->setMaxConnectionsPerIp(20);

// add your applications
$server->registerApplication('status', \Bloatless\WebSocket\Application\StatusApplication::getInstance());
$server->registerApplication('chat', \Bloatless\WebSocket\Examples\Application\Chat::getInstance());

// start the server
$server->run();

假设这段代码在一个名为server.php的文件中,您可以使用以下命令启动服务器

php server.php

然后,WebSocket服务器将监听提供的host和port上的新连接。默认情况下,这将是在localhost:8000

此存储库还包括一个在examples/server.php中的有效示例

应用

WebSocket服务器本身处理连接,但没有额外的逻辑就相当无用了。这种逻辑是通过应用程序添加的。在上述示例中,两个应用程序被添加到服务器:statuschat

您应用程序中最重要的方法将是

interface ApplicationInterface
{
    public function onConnect(Connection $connection): void;

    public function onDisconnect(Connection $connection): void;

    public function onData(string $data, Connection $client): void;

    public function onIPCData(array $data): void;
}

onConnectonDisconnect可用于跟踪连接到您应用程序的所有客户端。onData将在WebSocket服务器从连接到应用程序的客户端接收新数据时被调用。onIPCData将在您的机器上的另一个进程提供数据时被调用。(参见推送客户端(IPC)

一个应用程序的有效示例可以在examples/Application/Chat.php中找到

定时器

对于长时间运行的过程,如WebSocket服务器,通常需要定期执行任务。这可以通过定时器完成。定时器可以定期执行服务器或应用程序中的方法。以下是一个示例

$server = new \Bloatless\WebSocket\Server('127.0.0.1', 8000, '/tmp/phpwss.sock');
$chat = \Bloatless\WebSocket\Examples\Application\Chat::getInstance();
$server->addTimer(5000, function () use ($chat) {
    $chat->someMethod();
});
$server->registerApplication('chat', $chat);

此示例将每5秒调用您聊天应用程序中的someMethod方法。

推送客户端(IPC)

通常需要从另一个应用程序将数据推送到WebSocket服务器进程。假设您运行了一个包含聊天和一个包含新闻或博客区域的网站。现在每次您的博客发布新文章时,您都希望通知所有在聊天中的人。为此,您需要将博客逻辑中的数据推送到WebSocket服务器。这就是Push-Client的作用。

当启动WebSocket服务器时,它会打开一个Unix域套接字并监听新消息。然后,Push-Client可以用于发送这些消息。以下是一个示例

$pushClient = new \Bloatless\WebSocket\PushClient('//tmp/phpwss.sock');
$pushClient->sendToApplication('chat', [
    'action' => 'echo',
    'data' => 'New blog post was published!',
]);

以下代码将数据推送到您的运行中的WebSocket服务器进程。在这种情况下,聊天应用程序中的echo方法被调用,并将提供的信息发送给所有连接的客户端。

您可以在以下链接中找到完整的示例:examples/push.php

重要提示:推消息的大小不能超过64KB!

客户端(浏览器/JS)

以上内容都与服务器端相关。但是,如何从您的浏览器连接到服务器呢?

这里有一个简单的示例

<script>
 // connect to chat application on server
let serverUrl = 'ws://127.0.0.1:8000/chat';
let socket = new WebSocket(serverUrl);

// log new messages to console
socket.onmessage = (msg) => {
    let response = JSON.parse(msg.data);
    console.log(response.data);
};
</script>

这段javascript连接到服务器上的聊天应用,并将所有收到的消息打印到控制台。

更好的聊天客户端示例可以在以下位置找到:examples/public/chat.html

预期用途和限制

此项目主要是为了教育目的而构建的。代码相对简单易懂。这个服务器未在生产环境中进行测试,所以我强烈建议不要将其用于实际项目。对于小型教育项目或内部工具来说应该完全没问题,但很可能无法很好地处理大量流量或连接。

此外,一些“功能”是按设计故意缺失的

  • 不支持SSL。如果需要,可以使用如nginx之类的反向代理。
  • 不支持二进制消息。
  • 还有许多其他我甚至都没有意识到的事情 ;)

如果您需要更“健壮”的用PHP编写的websocket服务器,请查看以下优秀的替代方案。

替代方案

许可

MIT