0002 workerman针对官网测试例子的分析

这是0001中官网的例子,引入部分不谈

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是客户端发出的数据

关闭连接暂时不看,可广播的例子差不多,至此,我们的一个简陋的聊天工具分析完毕

你可能感兴趣的:(0002 workerman针对官网测试例子的分析)