2

我正在尝试使用 php 实现 websocket 并作为 yii 的扩展,以便我可以为我的 web 应用程序创建类似通知的功能

下面链接中的代码是我的起点:

http://www.flynsarmy.com/2012/02/php-websocket-chat-application-2-0/

它在我当地的 xampp 中完美运行。

我尝试将其转换为我遵循的 Yii 扩展步骤..

  1. 我已将 PHPWebSocket.php 类放在 yii 扩展文件夹中。
  2. 我创建了一个控制器 websocket 和一个动作 startserver 和一个动作索引(用于聊天界面以测试上面链接中的示例)

这是代码片段

<?php

Yii::import("ext.websocket.PHPWebSocket");

class WebSocketController extends Controller {

    public $layout = '//layouts/empty';

    public function actionStartServer() {

        set_time_limit(0);

        function wsOnMessage($clientID, $message, $messageLength, $binary) {
            global $Server;
            $ip = long2ip($Server->wsClients[$clientID][6]);

            // check if message length is 0
            if ($messageLength == 0) {
                $Server->wsClose($clientID);
                return;
            }

            //The speaker is the only person in the room. Don't let them feel lonely.
            if (sizeof($Server->wsClients) == 1)
                $Server->wsSend($clientID, "There isn't anyone else in the room, but I'll still listen to you. --Your Trusty Server");
            else
            //Send the message to everyone but the person who said it
                foreach ($Server->wsClients as $id => $client)
                    if ($id != $clientID)
                        $Server->wsSend($id, "Visitor $clientID ($ip) said \"$message\"");
        }

// when a client connects
        function wsOnOpen($clientID) {
            global $Server;
            $ip = long2ip($Server->wsClients[$clientID][6]);

            $Server->log("$ip ($clientID) has connected.");

            //Send a join notice to everyone but the person who joined
            foreach ($Server->wsClients as $id => $client)
                if ($id != $clientID)
                    $Server->wsSend($id, "Visitor $clientID ($ip) has joined the room.");
        }

// when a client closes or lost connection
        function wsOnClose($clientID, $status) {
            global $Server;
            $ip = long2ip($Server->wsClients[$clientID][6]);

            $Server->log("$ip ($clientID) has disconnected.");

            //Send a user left notice to everyone in the room
            foreach ($Server->wsClients as $id => $client)
                $Server->wsSend($id, "Visitor $clientID ($ip) has left the room.");
        }

        $Server = new PHPWebSocket();
        $Server->bind('message', 'wsOnMessage');
        $Server->bind('open', 'wsOnOpen');
        $Server->bind('close', 'wsOnClose');

        $Server->wsStartServer('127.0.0.1', 9300);
    }

    public function actionIndex() {
        $this->render('index');
    }

}

我使用 php 创建 websocket 的方法是正确的还是不可能这样做..

我只想使用 php 来实现相同的功能,因为我更喜欢使用 node.js 或任何其他脚本

4

2 回答 2

1

将 PHP 与 Apache 一起使用时,对 PHP 的每个请求(通常)都会创建新的进程/线程。由于 Web 套接字(在某种程度上)是永久连接,因此这些 PHP 请求会持续相当长的一段时间。每个进程都占用服务器上的内存。因此,我认为这是可能的,如果您一次有很多(甚至不是很多)用户在线,您的服务器可能会崩溃或拒绝请求。

Node.js 方法不同——每个连接不需要单独的进程,因此它可以一次处理许多活动连接。

您可以将 Node.js 与 PHP 一起使用,使用队列或其他一些通信机制将这两者连接起来。

于 2013-01-06T15:28:26.643 回答
0

以防万一其他人偶然发现这一点。

我一直在寻找一种方法来自己实现对 Yii 应用程序的实时事件。

在上面的评论中,提到了这个关于 HTML5 SSE的 (Yii) 教程。由于它看起来很简单,但如果您需要支持较旧的浏览器和移动设备,这还不够。

浏览器支持也可以在 IE 中工作吗? Internet Explorer 和 Android 浏览器(所有版本)不支持开箱即用的服务器发送事件。旧版本的 Firefox (< 6)、Chrome (< 6)、Safari (< 5)、iOS Safari (< 4) 或 Opera (< 11) 也不行。

另一个解决方案是一个相当新的Yii 节点套接字扩展。它基于node.js socket.io 库,使用elephant.io通过php 与服务器通信。最重要的是,扩展似乎(我只使用了一个月)写得很好。它同时支持 Linux 和 Windows,使用 CLI 执行命令,甚至还提供了自己的数据库驱动程序。

仍然欢迎其他解决方案。

于 2014-03-18T22:25:23.987 回答