不使用数据库或文件的php网络聊天
我正在尝试使用PHP实现一个实时聊天应用程序。是否可以不使用数据库或文件等持久数据存储来实现这一点。基本上我需要的是一个用PHP编写的中介不使用数据库或文件的php网络聊天,php,design-patterns,web-applications,Php,Design Patterns,Web Applications,我正在尝试使用PHP实现一个实时聊天应用程序。是否可以不使用数据库或文件等持久数据存储来实现这一点。基本上我需要的是一个用PHP编写的中介 接受来自客户端浏览器的消息 将消息广播到其他客户端 忘记留言 如果您只需要使用PHP,那么您可以将聊天消息存储在会话变量中,会话可以像对象一样,存储大量信息。 若您可以使用jQuery,那个么您可以在消息发送后将段落附加到div,但若站点被刷新,消息就会消失。 或者组合,在会话中存储消息,并使用jQuery和ajax进行更新。简而言之,您不能。 当前的HTT
如果您只需要使用PHP,那么您可以将聊天消息存储在会话变量中,会话可以像对象一样,存储大量信息。 若您可以使用jQuery,那个么您可以在消息发送后将段落附加到div,但若站点被刷新,消息就会消失。
或者组合,在会话中存储消息,并使用jQuery和ajax进行更新。简而言之,您不能。 当前的HTTP/HTML实现不支持
pushstate
,因此聊天应用程序的算法应遵循:
- 这意味着数据必须保存在全局中,如数据库或文件系统
您需要使用某种存储作为缓冲区。不使用文件或数据库(也使用文件)是不可取的。您可以尝试使用php函数,但我不知道任何有效的解决方案,因此您必须从头开始使用。尝试查看套接字库,就像它们允许即时传输消息,并且比TCP更快,而且是实时的一样。他们的基础设施允许在A点和B点之间即时发送数据,而无需先将数据存储在任何位置(尽管您仍然可以选择)。
这里有一个你应该看看html5的网络套接字。它使用双向连接,所以您不需要任何数据库或文件。任何发送到服务器的聊天信息都将直接发送到其他用户的浏览器,而无需任何Ajax调用。但您还需要设置web套接字服务器
<?php
// Set time limit to indefinite execution
set_time_limit (0);
// Set the ip and port we will listen on
$address = '192.168.0.100';
$port = 9000;
$max_clients = 10;
// Array that will hold client information
$clients = Array();
// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
// Bind the socket to an address/port
socket_bind($sock, $address, $port) or die('Could not bind to address');
// Start listening for connections
socket_listen($sock);
// Loop continuously
while (true) {
// Setup clients listen socket for reading
$read[0] = $sock;
for ($i = 0; $i < $max_clients; $i++)
{
if ($client[$i]['sock'] != null)
$read[$i + 1] = $client[$i]['sock'] ;
}
// Set up a blocking call to socket_select()
$ready = socket_select($read,null,null,null);
/* if a new connection is being made add it to the client array */
if (in_array($sock, $read)) {
for ($i = 0; $i < $max_clients; $i++)
{
if ($client[$i]['sock'] == null) {
$client[$i]['sock'] = socket_accept($sock);
break;
}
elseif ($i == $max_clients - 1)
print ("too many clients")
}
if (--$ready <= 0)
continue;
} // end if in_array
// If a client is trying to write - handle it now
for ($i = 0; $i < $max_clients; $i++) // for each client
{
if (in_array($client[$i]['sock'] , $read))
{
$input = socket_read($client[$i]['sock'] , 1024);
if ($input == null) {
// Zero length string meaning disconnected
unset($client[$i]);
}
$n = trim($input);
if ($input == 'exit') {
// requested disconnect
socket_close($client[$i]['sock']);
} elseif ($input) {
// strip white spaces and write back to user
$output = ereg_replace("[ \t\n\r]","",$input).chr(0);
socket_write($client[$i]['sock'],$output);
}
} else {
// Close the socket
socket_close($client[$i]['sock']);
unset($client[$i]);
}
}
} // end while
// Close the master sockets
socket_close($sock);
?>
Web套接字也用于许多实时应用程序中。我很快计划写一篇关于这方面的完整教程。我会通知您。您将要使用
套接字。本文将详细介绍您想要做的事情:
有没有可能不使用像这样的持久数据存储
数据库还是文件
这是可能的,但您不应该使用。基于数据库或文件不会减慢聊天速度。它将为您的聊天应用程序提供额外的安全性。您可以使用ajax和sockets进行基于web的聊天,而无需持久数据
您应该看到以下帖子:
实现这一点的一个解决方案是编写一个PHP套接字服务器
<?php
// Set time limit to indefinite execution
set_time_limit (0);
// Set the ip and port we will listen on
$address = '192.168.0.100';
$port = 9000;
$max_clients = 10;
// Array that will hold client information
$clients = Array();
// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
// Bind the socket to an address/port
socket_bind($sock, $address, $port) or die('Could not bind to address');
// Start listening for connections
socket_listen($sock);
// Loop continuously
while (true) {
// Setup clients listen socket for reading
$read[0] = $sock;
for ($i = 0; $i < $max_clients; $i++)
{
if ($client[$i]['sock'] != null)
$read[$i + 1] = $client[$i]['sock'] ;
}
// Set up a blocking call to socket_select()
$ready = socket_select($read,null,null,null);
/* if a new connection is being made add it to the client array */
if (in_array($sock, $read)) {
for ($i = 0; $i < $max_clients; $i++)
{
if ($client[$i]['sock'] == null) {
$client[$i]['sock'] = socket_accept($sock);
break;
}
elseif ($i == $max_clients - 1)
print ("too many clients")
}
if (--$ready <= 0)
continue;
} // end if in_array
// If a client is trying to write - handle it now
for ($i = 0; $i < $max_clients; $i++) // for each client
{
if (in_array($client[$i]['sock'] , $read))
{
$input = socket_read($client[$i]['sock'] , 1024);
if ($input == null) {
// Zero length string meaning disconnected
unset($client[$i]);
}
$n = trim($input);
if ($input == 'exit') {
// requested disconnect
socket_close($client[$i]['sock']);
} elseif ($input) {
// strip white spaces and write back to user
$output = ereg_replace("[ \t\n\r]","",$input).chr(0);
socket_write($client[$i]['sock'],$output);
}
} else {
// Close the socket
socket_close($client[$i]['sock']);
unset($client[$i]);
}
}
} // end while
// Close the master sockets
socket_close($sock);
?>
您可以通过命令行运行它来执行此操作,并且必须始终运行PHP客户端才能连接到它。然后,您可以编写一个连接到套接字的PHP客户端
<?php
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
您必须使用某种类型的ajax来调用jQuery,并将消息发布到此PHP客户端
http://php.net/manual/en/function.fsockopen.php我只是尝试了一些我以前从未做过的事情来回答这个问题。似乎有效,但我只测试了一次。我没有使用套接字,而是想到了使用共享会话变量。基本上,我强制Session_id为相同的值,而不管用户是谁,因此它们都共享相同的数据。从快速测试来看,它似乎有效。以下是我所做的:
session_id('12345');
session_start();
$session_id = session_id();
$_SESSION['test'] = $_SESSION['test'] + 1;
echo "session: {$session_id} test: {$_SESSION['test']} <br />";
session_id('12345');
会话_start();
$session_id=session_id();
$_会话['test']=$_会话['test']+1;
echo“session:{$session_id}test:{$_session['test']}
”;
所以我的想法是,您可以简单地将聊天信息存储在会话变量中,并强制每个人使用共享会话,而不管他们是谁。然后,您可以简单地使用ajax不断地重新加载当前会话变量,并在添加消息时使用ajax编辑会话变量。此外,您可能希望将会话设置为永不过期或具有很长的maxlifetime
正如我所说的,我只是花了几分钟的时间来研究它是否有效。PHP不适合您的要求(在apache PHP、fastcgi等正常设置中),因为PHP脚本对于每个请求都从上到下执行,并且在不使用外部服务或数据库/文件的情况下无法在请求之间保持任何状态(例如,除此之外,但它不用于实现聊天,也不会扩展到多个服务器)
您肯定应该看看Node.js,尤其是Node.js模块Socket.IO(一个Websocket库)。这是难以置信的易于使用和岩石。IO还可以通过可选的redis后端扩展到多个聊天服务器,这意味着更容易扩展
顺便说一下,尝试使用带有静态会话id的$\u SESSION
作为通信通道不是一个解决方案,因为PHP将会话数据保存到文件中。最好使用node.js服务器。WebSocket现在不再是跨浏览器的了(除了node.js的socket.io,它工作得非常完美)当我试图解决同样的问题时,我选择了Nginx。我之所以选择这种方式,是因为我必须支持较旧的浏览器(通常不支持WebSockets),并且没有信心在TCP代理之后设置合适的解决方案
工作流程如下所示:
客户端通过长轮询连接到我的/subscriber
位置,该位置对所有人开放
/publisher
位置仅接受来自我自己服务器的连接
当客户机订阅和交谈时,它基本上只是要求一个PHP脚本来处理什么