这是0001中官网的例子,引入部分不谈
<?php
use Workerman\Worker;
require_once '/workerman/Autoloader.php';
$global_uid = 0;
// 当客户端连上来时分配uid,并保存连接,并通知所有客户端
function handle_connection($connection)
{
global $text_worker, $global_uid;
// 为这个链接分配一个uid
$connection->uid = ++$global_uid;
}
// 当客户端发送消息过来时,转发给所有人
function handle_message($connection, $data)
{
global $text_worker;
foreach($text_worker->connections as $conn)
{
$conn->send("user[{$connection->uid}] said: $data");
}
}
// 当客户端断开时,广播给所有客户端
function handle_close($connection)
{
global $text_worker;
foreach($text_worker->connections as $conn)
{
$conn->send("user[{$connection->uid}] logout");
}
}
// 创建一个文本协议的Worker监听2347接口
$text_worker = new Worker("text://0.0.0.0:2347");
// 只启动1个进程,这样方便客户端之间传输数据
$text_worker->count = 1;
$text_worker->onConnect = 'handle_connection';
$text_worker->onMessage = 'handle_message';
$text_worker->onClose = 'handle_close';
Worker::runAll();
先看下面这一段
// 创建一个文本协议的Worker监听2347接口
$text_worker = new Worker("text://0.0.0.0:2347");
// 只启动1个进程,这样方便客户端之间传输数据
$text_worker->count = 1;
$text_worker->onConnect = 'handle_connection';
$text_worker->onMessage = 'handle_message';
$text_worker->onClose = 'handle_close';
Worker::runAll();
由于workerman是对一个端口监听的,那么,我们需要创建一个对端口的监听类也就是Worker对吧,但是类呢,本身是抽象的,需要对对这个类进行实例化,有了$text_worker对象,所以有了
// 创建一个文本协议的Worker监听2347接口
$text_worker = new Worker("text://0.0.0.0:2347");
接下来的操作我们不关心Worker类,只关心$text_worker对象,值得注意的是,$text_worker对象的方法来自于Worker类。
由于workerman只有同进程才能互传数据,那么为了方便测试只启动一个进程
// 只启动1个进程,这样方便客户端之间传输数据
$text_worker->count = 1;
对workerman配置好之后启动,这句话固定,目前探讨的意义不大
Worker::runAll();
可以说上面那些都是固定的部分,可以不用理会,那么,下面,我们重点看下这三个地方
$text_worker->onConnect = 'handle_connection';//连接到服务器
$text_worker->onMessage = 'handle_message';//传输数据
$text_worker->onClose = 'handle_close';//关闭连接/服务
注释已给出,可以看到,我们给了一个Worker的实例化对象$text_worker,那么这个对象肯定有方法,他有三个方法,链接,传数据,关闭连接,分别对应onConnect,onMessage ,onClose 。
我们可以看到onConnect,onMessage ,onClose分别对应了一个方法handle_connection,handle_message,handle_close这些个方法,实现在test001.php里头
function handle_connection($connection)
{
global $text_worker, $global_uid;
// 为这个链接分配一个uid
$connection->uid = ++$global_uid;
}
// 当客户端发送消息过来时,转发给所有人
function handle_message($connection, $data)
{
global $text_worker;
foreach($text_worker->connections as $conn)
{
$conn->send("user[{$connection->uid}] said: $data");
}
}
// 当客户端断开时,广播给所有客户端
function handle_close($connection)
{
global $text_worker;
foreach($text_worker->connections as $conn)
{
$conn->send("user[{$connection->uid}] logout");
}
}
单单说连接部分,一个客户端刚连上来的时候需要做一些记录操作
$global_uid = 0;//一个全局变量
function handle_connection($connection)
{
global $text_worker, $global_uid;
// 为这个链接分配一个uid
$connection->uid = ++$global_uid;
}
我们可以看到,初始化了一个全局的$global_uid ,每一个连接($connection)连上来,就会给这个连接分配一个id号,这个id号为了方便就是全局变量自增1
当一个客户端发送数据,或者服务端发送数据的时候,需要做下面的操作,也就是说,在初步的学习中,我们的一些业务逻辑实际上,可以在"handle_message()"这个方法里头去实现
function handle_message($connection, $data)
{
global $text_worker;
foreach($text_worker->connections as $conn)
{
$conn->send("user[{$connection->uid}] said: $data");
}
}
$text_worker服务端包含了所有已连接上的所有客户端的信息,所以遍历$text_worker的connections ,也就是连接上来的客户端,用send方法逐个的发送,就可以广播给所有的客户端消息,而handle_message($connection, $data)这里面的$connection是发出消息的客户端,$data是客户端发出的数据
关闭连接暂时不看,可广播的例子差不多,至此,我们的一个简陋的聊天工具分析完毕