【问题标题】:Creating a client for a chat in PHP在 PHP 中为聊天创建客户端
【发布时间】:2012-12-03 20:54:56
【问题描述】:

我正在尝试创建一个PHP 聊天,所以我有server.php 来启动终端上的服务器,即监听client 连接:

<?php

function chat_leave( $sock, $chat_id = 0 )
{
    if( $chat_room_id[ $chat_id ] )
    {
        unset( $chat_room_id[ $chat_id ] ); 
        return true;
    }
    socket_close($sock);
    return false;
}

function client( $input )
{
    /*
    Simple php udp socket client
    */

    //Reduce errors
    error_reporting(~E_WARNING);

    $server = '127.0.0.1';
    $port = 9999;

    if(!($sock = socket_create(AF_INET, SOCK_DGRAM, 0)))
    {
        $errorcode = socket_last_error();
        $errormsg = socket_strerror($errorcode);

        die("Couldn't create socket: [$errorcode] $errormsg \n");
    }

    //Communication loop
    while(1)
    {

        //Send the message to the server
        if( ! socket_sendto($sock, $input , strlen($input) , 0 , $server , $port))
        {
            $errorcode = socket_last_error();
            $errormsg = socket_strerror($errorcode);

            die("Could not send data: [$errorcode] $errormsg \n");
        }

        //Now receive reply from server and print it
        if(socket_recv ( $sock , $reply , 2045 , MSG_WAITALL ) === FALSE)
        {
            $errorcode = socket_last_error();
            $errormsg = socket_strerror($errorcode);

            die("Could not receive data: [$errorcode] $errormsg \n");
        }

        return $reply;
    }
}
/*
 * chat_join
 * a new user joins the chat
 * @username: String
 * @password: String
 * 
 * add a new listener to the server
 * 
 */
function chat_join( $username = "", $password = "" )
{
    $users = array(
        "batman" => "batman123",
        "robin"  => "robin123",
        "joe"    => "joe123"
    );
    if( $users[$username] == $password )
    {
        return true;
    }

    return false;   
}
function main()
{
    $chat_room_id = array();

    $username = stripslashes( $_POST['username'] );
    $password = stripslashes( $_POST['password'] );
    $action   = stripslashes( $_POST['action'] );
    $port     = intval( $_POST['port'] );
    $domain   = stripslashes( $_POST['domain'] );
    $chat_id  = intval( $_POST['chat_room_id'] );

    if( strcmp( $action, "login" ) == 0 )
    {
        $status = chat_join( $username, $password );
        if( $status )
        {
            $chat_room_id[] = $chat_id;
            echo json_encode( $status );
        }
    }
    else if( strcmp( $action, "chat" ) == 0 )
    {
        $msg = stripslashes( $_POST['message'] );
        // take the message, send through the client
        $reply = client( $msg );
        echo json_encode( $reply );
    }
    else if( strcmp( $action, "logout") == 0 )
    {

    }
    else
    {
        echo json_encode( false );
    }
    return;
}

main();

?>

函数client() 是我从client.php 文件中获得的代码,当我在终端上执行它时,它能够发送和接收来自server.php 的消息。现在我想使用我的main.php 文件,所以一旦用户登录,他将向服务器发送消息,服务器将回复用户没有看到的消息。 当我从两个不同的终端运行server.phpclient.php 时,我可以发送和接收消息,但是我想使用main.php 来做到这一点,将回复消息转换为JSON 对象并发回到html 页面,它将被附加到textarea 框。 我的问题是:如何获得client.php 收到的回复并将其发送回html页面? 当我在终端上执行它时,我有:

Enter a message to send : hello
Reply : hello

我使用AJAX 发送聊天中的用户输入,所以我希望能够接收该消息,并将其发送到服务器,我在终端上启动并将回复返回并转发到网页并将其附加到文本框区域。 我怎样才能做到这一点?我应该通过main.phpclient.php 作为服务启动吗?还是应该使用client($input) 函数发送消息,然后返回它发送的内容? 但是,我希望 client 在用户注销之前一直运行,因为其他客户端可能会连接到聊天。我怎么能做到这一点对我来说有点模糊。 client( $input )中的代码与client.php中的代码相同。

【问题讨论】:

  • 另外请记住,PHP 并非旨在运行超过一个请求。它可以运行更长时间(前一段时间做过聊天机器人),但如果你不是很小心,你很有可能会泄漏内存和崩溃。其他语言可能更适合常驻应用。

标签: php html ajax json


【解决方案1】:

在使用 PHP 和 jQuery 之前,我按照这些思路开发了一些东西。我寻求的解决方案是由于服务器设置的限制(我无法控制)。我使用 PHP 核心脚本创建了从消息窗口到消息提交框的整个页面布局。任何来到该页面的用户都会获得一个随机生成的用户,例如 user123234234,从他们进入聊天页面时开始生成一个 unix 时间戳。

所有提交的消息都存储在一个 XML 文件中,并且每天都会创建一个新的 XML 文件。用户被保存在如下消息节点中,其中包含使用不同节点属性的每条消息的用户详细信息。

消息窗口每 5 秒刷新一次,使用 jquery AJAX 调用另一个 PHP 脚本,该脚本仅从用户进入聊天页面时读取 XML 文件。

<messages>
    <message user="user123456" ip="127.0.0.1" session="{users session ID here}" time="{unix timestamp}"><![CDATA[User message here]]></message>
</messages>

它背后有更多的逻辑,但我发现它最容易开发和维护,我希望它能帮助你指明正确的方向。它适用于所有主流浏览器和 IE7+。

【讨论】:

    【解决方案2】:

    据我了解您的问题,您想从客户端向服务器发送一条消息,一旦这条消息到达服务器,它将回复所有客户端...我是对的???

    我进行了一些聊天,例如使用 nodejs 和其他 javascripts 技术......并且必须说这里的一个很好的选择是使用网络套接字。意识到browser support is limited,但由于您没有指定运行它需要哪些浏览器,我认为这是一个很好的方法。

    查看相关链接:

    How to Use Sockets in JavaScript\HTML?

    http://socket.io/

    仅使用 php + js 的一种可能方法是创建一些函数并放入 setInterval 以每 12 秒向服务器发出请求。我在 2005 年使用这种方法进行了某种 asp 聊天。我必须说网络套接字要好得多。

    我不知道这是否能回答您的问题...请告诉我!

    【讨论】:

    • Websocket 支持实际上在当前所有桌面浏览器中都是通用的,并且 node.js 有足够的回退,因此它可以在 IE5.5 之后的所有浏览器上运行。
    【解决方案3】:

    我想我明白发生了什么。听起来你可能缺少一个听众?通常聊天程序有客户端 ajax 定期检查或“监听”特定用户的消息。

    例如,如果有人在您的数据库(或您存储消息的任何地方)中为用户 x 留下了一条消息,那么您可能有一些 javascript 每秒调用一个 php 脚本来查看服务器上是否有任何消息对于用户 x。如果有,您可以回显一条或多条消息,并通过您的 ajax 回调函数接收它们。

    如果您熟悉 jQuery,请查看 $.get 方法:http://api.jquery.com/jQuery.get/

    【讨论】:

      【解决方案4】:

      抱歉跑题了,但如果可以的话,最好使用 XMPP 就绪的解决方案,比如带有 http-bind 模块的 ejabberd 服务器。当然,这样的解决方案有一些缺点,但缺点更大。看看这个解决方案,也许它会以低成本解决您的问题。

      related answer with brief desc on XMPP solution

      【讨论】:

        猜你喜欢
        • 2011-01-04
        • 1970-01-01
        • 2012-06-18
        • 1970-01-01
        • 1970-01-01
        • 2011-12-26
        • 2015-10-12
        • 1970-01-01
        • 2023-03-29
        相关资源
        最近更新 更多