The PHP libevent extension has a very powerful feature. The following excerpt from Baidu Encyclopedia:
Libevent is a C language, lightweight open-source high-performance network library, mainly has the following several highlights: event-driven (Event-driven), high-performance, lightweight, focus on the network, not as large as ACE;
The source code is quite refined, easy to read, cross-platform, support Windows, Linux, *bsd and Mac Os, support multiple I/O multiplexing technology, Epoll, poll, Dev/poll, select and Kqueue, etc., support I/O,
Events such as timers and signals; Register event priority.
The libevent extension in PHP has the following functions:
Event_base_free () frees the resource, which cannot destroy the binding event
Event_base_loop () Handles events and handles event loops based on the specified base
Event_base_loopbreak () immediately cancels the event loop, with the same behavior as the break statement
Event_base_loopexit () exits the loop after a specified time
Event_base_new () creation and initial events
Event_base_priority_init () Sets the priority of the event
Event_base_set () Associating events to event base
Event_buffer_base_set () Associating cached events to Event_base
Event_buffer_disable () disabling a cached event
Event_buffer_enable () enable a specified cached event
Event_buffer_fd_set () Change the file system description of a cache
Event_buffer_free () releasing cache events
Event_buffer_new () to create a new cache event
Event_buffer_priority_set () Priority setting for cache events
Event_buffer_read () reading data from a cache event
Event_buffer_set_callback () Sets or resets the callback Hansh function to the cached event
Event_buffer_timeout_set () sets the read and write time to timeout for a cached event
Event_buffer_watermark_set setting watermark flags for read and write events
Event_buffer_write () writes data to the cache event
Event_add () Adds an execution event to the specified settings
Event_del () Removing events from the set events
Event_free () empty event handle
Event_new () Create a new event
Event_set () Prepare to add an event in Event_add
Event_set explanation of some parameters:
(a) Ev_timeout: timeout
(b) Ev_read: As long as there is data in the network buffer, the callback function is triggered
(c) Ev_write: The callback function is triggered whenever the data that is plugged into the network buffer is written out
(d) ev_signal:posix signal volume
(e) Ev_persist: If this attribute is not specified, the event will be deleted after the callback function is triggered
(f) Ev_et:edge-trigger edge triggering
Let's take a look at a simple use case:
123456789101112131415161718192021222324 |
<?php
$socket = stream_socket_server(
"tcp://0.0.0.0:8000"
,
$errno
,
$errstr
);
$base
= event_base_new();
$event
= event_new();
function
read_cb(
$socket
,
$flag
,
$base
) {
fread
(
$socket
);
fwrite(
"hello world\n"
);
}
function
accept_cb(
$socket
,
$flag
,
$base
) {
$conn
= stream_socket_accept(
$socket
, 0);
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
);
}
event_set(
$event
,
$socket
, EV_READ | EV_PERSIST,
‘accept_cb‘
,
$base
);
event_base_set(
$event
,
$base
);
event_add(
$event
);
event_base_loop(
$base
);
|
This paragraph is a simple use case of a PPT from Hantian, let me explain to you:
First, create a TCP service that binds 8000 ports. Create a event_base, and then create an event that allows the event to listen to the newly created socket via the Event_set settings and set the properties for the event, and you can see that the callback function is specified ACCEPT_CB
This event is then bound to base and added to the listener event to initiate the events loop.
It can be found that ACCEPT_CB has accepted the client link and created an event to do the same thing as before, and the callback function that specifies the event is READ_CB. The READ_CB function does a read and write operation.
Below I myself by finishing writing a client client.php
123456789101112131415 |
<?php
/**
* author: NickBai
* createTime: 2016/12/17 0017 下午 3:00
*/
$socket_client
= stream_socket_client(
‘tcp://127.0.0.1:2000‘
,
$errno
,
$errstr
, 30);
fwrite(
$socket_client
,
"hello world!"
);
sleep(1);
$return
=
fread
(
$socket_client
, 1024);
echo
"come from server : "
.
$return
. PHP_EOL;
sleep(2);
fwrite(
$socket_client
,
"send again!"
);
$return
=
fread
(
$socket_client
, 1024);
echo
"come from server : "
.
$return
. PHP_EOL;
|
I've re-organized a server service-side code with actual operations as follows
server.php
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2016/12/17
* Time: 20:59
*/
$socket
= stream_socket_server(
"tcp://0.0.0.0:2000"
,
$errno
,
$errstr
);
$base
= event_base_new();
$event
= event_new();
event_set(
$event
,
$socket
, EV_READ | EV_PERSIST,
‘accept_cb‘
,
$base
);
event_base_set(
$event
,
$base
);
event_add(
$event
);
event_base_loop(
$base
);
function
read_cb(
$buffer
)
{
static
$ct
= 0;
$ct_last
=
$ct
;
$ct_data
=
‘‘
;
while
(
$read = event_buffer_read(
$buffer
, 1024)) {
$ct
+=
strlen
(
$read
);
$ct_data
.=
$read
;
}
$ct_size
= (
$ct
-
$ct_last
) * 8;
echo
"client say : "
.
$ct_data
.PHP_EOL;
event_buffer_write(
$buffer
,
"Received $ct_size byte data"
);
}
function
write_cb(
$buffer
)
{
echo
"我在打酱油 "
. PHP_EOL;
} function
error_cb(
$buffer
,
$error
)
{
// 客户端断开连接之后,清除
event_buffer_disable(
$GLOBALS
[
‘buffer‘
], EV_READ | EV_WRITE);
event_buffer_free(
$GLOBALS
[
‘buffer‘
]);
fclose(
$GLOBALS
[
‘connection‘
]);
unset(
$GLOBALS
[
‘buffer‘
],
$GLOBALS
[
‘connection‘
]);
}
function
accept_cb(
$socket
,
$flag
,
$base
)
{
$connection
= stream_socket_accept(
$socket
);
stream_set_blocking(
$connection
, 0);
$buffer
= event_buffer_new(
$connection
,
‘read_cb‘
,
‘write_cb‘
,
‘error_cb‘
);
event_buffer_base_set(
$buffer
,
$base
);
event_buffer_timeout_set(
$buffer
, 30, 30);
event_buffer_watermark_set(
$buffer
, EV_READ, 0, 0xffffff);
event_buffer_priority_set(
$buffer
, 10);
event_buffer_enable(
$buffer
, EV_READ | EV_PERSIST);
// 必须将 $connection 和 $buffer 赋值给一个全局变量,否则无法生效
$GLOBALS
[
‘connection‘
] =
$connection
;
$GLOBALS
[
‘buffer‘
] =
$buffer
;
}
|
Simple use cases for PHP libevent extensions