[英]PHP Socket Server Hangs
I've worked hours and hours on this, and I can't figure it out. 我已经花了几个小时的时间,但我无法弄清楚。 I've browsed the posts on here trying to find the solution also and to no avail.
我浏览了这里的帖子,试图找到解决方案,但无济于事。
I have a Socket Server setup for my browser-based game. 我为基于浏览器的游戏安装了Socket Server。 I've stripped it down trying to find the issue, and it seems that fread is hanging because if I comment out "fread($fp, 10024);"
我已将其剥离以查找问题,似乎fread正在挂起,因为如果我注释掉“ fread($ fp,10024);”, then it runs fine, but of course doesn't read the response.
那么它运行正常,但当然不会读取响应。
While I debug this, I've broken the files down to the basics. 在调试时,我将文件分解为基本内容。
I have the Socket Server: ChatServer.php 我有套接字服务器:ChatServer.php
set_time_limit(0);
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_get_option($sock, SOL_SOCKET, SO_REUSEADDR);
socket_bind($sock, "127.0.0.1", "9990");
socket_listen($sock, 4);
$chatContent = "Testing, 1, 2, 3.";
do
{
$childSocket = socket_accept($sock);
$incomingData = socket_read($childSocket, 12048);
socket_write($childSocket, $chatContent, strlen($chatContent));
} while(true);
Then I have Test.php which should open the socket and read a response. 然后我有Test.php,它应该打开套接字并读取响应。
$fp = fsockopen("127.0.0.1", "9990", $errno, $errstr, 5);
echo $errstr . "<br />";
echo fread($fp, 10024);
$errstr doesn't display an error, because when I start ChatServer.php then reload Test.php, it never reloads. $ errstr不会显示错误,因为当我启动ChatServer.php然后重新加载Test.php时,它永远不会重新加载。 It hangs for minutes and lags my entire server.
它挂了几分钟,滞后了我的整个服务器。 I'm running on a VPS.
我正在VPS上运行。 This worked fine before, then suddenly stopped working, and I can't figure out why.
在此之前效果很好,然后突然停止工作,我不知道为什么。
Edit: Thanks to GigaWatt, I was able to get it working. 编辑:感谢GigaWatt,我得以使其工作。 Here is the code I used if you have the same issue.
如果您遇到相同的问题,这是我使用的代码。 :)
:)
set_time_limit(0);
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_get_option($sock, SOL_SOCKET, SO_REUSEADDR);
socket_bind($sock, "127.0.0.1", "9990");
socket_listen($sock, 4);
$chatContent = "Testing, 1, 2, 3.";
do
{
$childSocket = socket_accept($sock);
$meta = stream_get_meta_data($sock);
if($meta['unread_bytes'] > 0) {
$incomingData = socket_read($childSocket, $meta['unread_bytes']);
}
socket_write($childSocket, $chatContent, strlen($chatContent));
} while(true);
Just use stream_get_meta_data and then unread_bytes. 只需使用stream_get_meta_data然后使用unread_bytes。
The call to socket_read
is a blocking call, meaning everything stops until the specified number of bytes have been read. 对
socket_read
的调用是一个阻塞调用,这意味着所有操作都将停止,直到已读取指定数量的字节为止。
If you need to continue processing, consider using stream_get_meta_data
(the unread_bytes
value) to check how much unread data is waiting. 如果需要继续处理,请考虑使用
stream_get_meta_data
( unread_bytes
值)来检查有多少未读数据正在等待。
Once it reaches the desired threshold, then call socket_read
. 一旦达到所需的阈值, 则调用
socket_read
。
http://us3.php.net/manual/en/function.stream-get-meta-data.php http://us3.php.net/manual/en/function.stream-get-meta-data.php
It does exactly what you tell it to: waits for 12048 / 10024 bytes of data or socket being closed. 它完全按照您的指示进行操作:等待12048/10024字节的数据或套接字被关闭。
You might be interested in using a non-blocking socket ( socket_set_nonblock/stream_set_blocking
) and a socket_select
loop or libevent. 您可能对使用非阻塞套接字(
socket_set_nonblock/stream_set_blocking
)和socket_select
循环或libevent socket_select
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.