<?php
$serv = stream_socket_server("tcp://0.0.0.0:2345", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN);
stream_set_blocking($serv, 0);
for ($i = 0; $i < 3; $i++) {
$pid = pcntl_fork();
if ($pid === 0) {
$base = event_base_new();
$event = event_new();
event_set($event, $serv, EV_READ | EV_PERSIST, 'accept_cb', $base);
event_base_set($event, $base);
event_add($event);
event_base_loop($base);
exit(0);
}
}
function accept_cb($socket, $flag, $base)
{
echo "onConnect\n";
$conn = @stream_socket_accept($socket, 0);
if(false === $conn)
{
return;
}
stream_set_blocking($conn, 0);
$event = event_new();
event_set($event, $conn, EV_READ | EV_PERSIST, 'read_cb', $base);
event_base_set($event, $base);
event_add($event);
}
function read_cb($conn, $flag, $base) {
echo "onMessage\n";
$data = fread($conn, 65535);
$res = "hello: $data" . PHP_EOL;
fwrite($conn, $res);
}
while(1) {
$status = 0;
$pid = pcntl_wait($status, WUNTRACED);
if ($pid > 0) {
echo "$pid onWorkerStop\n";
}
}
在没有用event之前,我是用一个进程来维持一个长连接,每个进程中用一个变量来动态保存这个连接,这样连接就不会断掉。
上面这段代码用了event,可以执行到accept_cb,但是这个时候连接就会断掉。
看到workerman源码中,是把连接存到了一个_socket属性中,在read时,并没有用这个属性,是使用event传递的socket,一切正常。
大神请问,我这段代码怎么拯救呢,让它连接不断掉。
首先你要理解为什么会断掉。
因为accept_cb函数里面$conn是个临时变量,函数之行完$conn就销毁了,那么链接就断开了。
我把accept_cb函数里的$conn 都存到一个全局数组里,这样就不会断开连接了。但是客户端发送消息,服务端没有走read_cb函数。
你要会举一反三
恩 已经弄明白了。event也要存起来。非常感谢!