php中文网最新课程

每日17点准时技术干货分享

为什么要写这篇文章?

我学习Workman好几次了,每次都失败(没做成想要的功能,原谅我比较笨)。但是这次也花了好几个小时,把之前没做成的功能实现了。

其实就是两个简单的功能:

一对一发送消息,广播消息(群聊)。

这个功能用swoole早都实现了,也是由于之前一直想用 think-worker 的原因,想想还是得自己琢磨才行,人家做好的框架或许是个阉割版。

别问我为什么不用swoole,因为 workman 可以在Windows中运行。

(1)首先,得简单说说 thinkphp+workerman 的安装。

安装 thinkphp5.1

composer create-project topthink/think=5.1.x-dev tp5andworkman

安装 think-worker

composer require topthink/think-worker=2.0.*

直接安装 workman

composer require workerman/workerman

(2)我们先看 think-worker 的代码

config/worker_server.php

先来个服务器广播消息的示例,每10秒钟定时广播一条消息

'onWorkerStart'  => function ($worker) {

    \Workerman\Lib\Timer::add(10, function()use($worker){

        // 遍历当前进程所有的客户端连接,发送自定义消息

        foreach($worker->connections as $connection){

            $send['name'] = '系统信息';

            $send['content'] = '这是一个定时任务信息';

            $send['time'] = time();

            $connection->send(json_encode($send));

        }

    });

}

但是在 onMessage 时,我们获取不到 $worker 对象,所以无法广播消息。

'onMessage'      => function ($connection, $data) {

    $origin = json_decode($data,true);

    $send['name'] = '广播数据';

    $send['content'] = $origin['content'];

    $message = json_encode($send);

    foreach($worker->connections as $connection)

    {

        $connection->send($message);

    }

}

尝试了各种方法,貌似都不行

'onMessage'      => function ($connection, $data)use($worker) {

    // 这样是获取不到 $worker 对象的

    // ...省略代码

}

所以只能抛弃 thinkphp 给我们封装的 think-worker 框架,得自己写,(或者修改框架内部代码)

修改框架内部的代码:

/vendor/topthink/think-worker/src/command/Server.php

主要是把 onMessage 方法自己加进去

use() 就是把外部变量传递到函数内部使用,或者使用global $worker

$worker = new Worker($socket, $context);

$worker->onMessage = function ($connection, $data)use($worker) {

    $origin = json_decode($data,true);

    $send['name'] = '广播数据';

    $send['content'] = $origin['content'];

    $send['uid'] = $connection->uid;

    $message = json_encode($send);

    foreach($worker->connections as $connection)

    {

        $connection->send($message);

    }

};

这样,我们就能够获取到 $worker 对象了

$worker->onMessage = function ($connection, $data)use($worker) { ... }

(3)$connection 绑定 uid

其实你早都已经看出,$worker->connections 获取到的是当前所有用户的连接,connections 即为其中一个链接。

记录websocket连接时间:

$worker->onConnect = function ($connection) {

    $connection->login_time = time();

};

获取websocket连接时间:

$worker->onMessage = function ($connection, $data)use($worker) {

    $login_time = $connection->login_time;

};

由此可以看出,我们可以把数据绑定到 $connection 连接的一个属性,例如:

$connection->uid = $uid;

当JavaScript端在连接websocket服务器成功后,即把自己的 uid 立马发送服务端绑定:

$worker->onMessage = function ($connection, $data)use($worker) {

    $origin = json_decode($data,true);

    if(array_key_exists('bind',$origin)){

        $connection->uid = $origin['uid'];

    }

};

(4)单播发送消息,即自定义发送

$worker->onMessage = function ($connection, $data)use($worker) {

    $origin = json_decode($data,true);

    $sendTo = $origin['sendto']; // 需要发送的对方的uid

    $content = $origin['content']; // 需要发送到对方的内容

    foreach($worker->connections as $connection)

    {

        if( $connection->uid == $sendTo){

            $connection->send($content);

        }

    }

};

到此,已经完成基于 workman 的自定义对象发送消息。

由于该php文件存放于composer中,只需要把该文件复制出来,放到application/command,修改命名空间,即可保存到自己的项目中

(5)对比swoole

1、workman可以在windows系统中运行,swoole则不能。

2、workman:$worker->connections获取所有连接,$connection->id获取自己的连接id;swoole:$server->connections获取所有连接,$connection->fd获取自己的连接id。

3、workman启动时执行 onWorkerStart 方法,可以把定时器写入到里面;swoole 使用 WorkerStart 启动定时器。

仅仅于聊天室或者定时器而言,workman 还是比较方便的。

-END-

声明:本文选自「 php中文网 」,搜索「 phpcnnew 」即可关注!

用webstorm做一个跑马灯_用Workman做一个聊天室相关推荐

  1. 基于阿里云用C/C++做了一个http协议与TCP协议的web聊天室的服务器——《干饭聊天室》

    基于阿里云用C/C++做了一个http协议与TCP协议的web聊天室的服务器--<干饭聊天室> 在这里首先感谢前端小伙伴飞鸟 前端技术请看一款基于React.C++,使用TCP/HTTP协 ...

  2. html跑马灯_用Excel居然能做“跑马灯”,而且还这么简单!

    我的目标:让中国的大学生走出校门的那一刻就已经具备这些office技能,让职场人士能高效使用office为其服务.支持我,也为自己加油! 你没看错,上面这个就是用Excel做出来的,不过要用到窗体和控 ...

  3. Vue.js 学习笔记 四 用一,二,三的知识做个跑马灯

    做个简单的跑马灯效果 页面定义2个按钮,绑定2个方法. <div id="divApp"><input type="button" value ...

  4. 写一个跑马灯程序并注释

    我可以写一个简单的跑马灯程序,代码如下:// 定义一个字符串,用于显示跑马灯 var str = '你好,世界!';// 定义一个变量,用于表示跑马灯的位置 var pos = 0;// 使用循环,不 ...

  5. 用html5做一个简单网页_用Python做一个简单的翻译工具

    编程本身是跟年龄无关的一件事,不论你现在是十四五岁,还是四五十岁,如果你热爱它,并且愿意持续投入其中,必定会有所收获. 本文就来自编程教室一位"小"读者的投稿(互助学习1群里的同学 ...

  6. python做一个小游戏_利用python做个小游戏

    从本期开始,我们将利用几天的时间用python来做个小游戏,当然,在做小游戏之前,我们必须学会一个做小游戏的第三方库--pygame.可能有人会说,python不擅长或者说不适合用来做游戏,的确是这样 ...

  7. python 适合做什么生意好_上班族副业做什么好?这10个总有一个让你赚到钱

    随着社会的快速发展,生存压力的日益增加.副业已经成为我们不得不考虑的改善生活品质的途径.尤其对于上班族来说,毕竟不是所有人都会成为职场精英,在自己的领域有着非凡的成就的.首先,在工作的压力下,除了完成 ...

  8. python做作业没头绪_使用Python做作业

    python做作业没头绪 Applying OpenCV and Tesseract to do your math-homework 应用OpenCV和Tesseract进行数学作业 The pos ...

  9. js动态创建两个div 把其中一个添加到另一个的里面_我开发了一个鸿蒙在线教育APP!...

    鸿蒙 2.0 已经发布了有段时间了,目前网上也有些小 demo 了,但是缺乏稍微大点的项目代码. 我准备计划开发一个稍微正式点的项目,我写了个初略的项目需求清单,来体验鸿蒙应用开发. 目前我已经着手实 ...

最新文章

  1. 【力荐】Select查询语句中LIKE关键词的优化方法分析
  2. Android应用程序签名详解
  3. python文件实时同步_python文件自动同步备份v1.2【运维必备】2020/12/31
  4. 从Java程序员进阶为架构师,全套16张图概括最全技能!建议收藏!
  5. 二叉树的建立与遍历(数据结构)
  6. max-height、min-height、height优先级的问题
  7. Python numpy中矩阵的用法总结
  8. ICTCLAS 汉语词性标注
  9. GitHub iOS开源项目
  10. 台式计算机读不到u盘怎么回事,电脑读不出u盘怎么办
  11. 第119章 SQL函数 RIGHT
  12. 苹果6怎么显示itunes store无法连接服务器,iPhone6 plus无法连接iTunes Store的原因和解决教程...
  13. 联想电脑拯救者y7000触摸屏失灵的修复方法
  14. Latex里一些特殊的数学符号
  15. python利用ffmpeg进行rtmp推流直播
  16. 谭浩强《C程序分析》(第五版)第七章
  17. 实现线程同步的几种方法
  18. android和MTKP60区别,联发科P60和骁龙625哪个好 骁龙625与联发科P60区别对比 (全文)...
  19. c语言循环码编码,二进制与循环码各有何特点
  20. VC++报错:无法打开源文件“new.h”...

热门文章

  1. java输入日期计算天数_(JAVA)输入年月日,计算日期是今年的第几天?
  2. mysql停止服务命令_0789不停止MySQL服务重做备库的方法
  3. 计算机网络体系结构(OSI七层、TCP/IP四层、五层协议)
  4. java 图像刺绣算法_图像处理:OpenCV3源代码文件解析
  5. 利用lrz、lsz工具在linux与windows之间传输文件
  6. windows10下配置环境变量
  7. 转:Webkit Flex伸缩盒模型属性备忘
  8. 2018-06-25-Python全栈开发day21-part2-time模块介绍
  9. Java的OOP三大特征之一——多态
  10. mysql补充(1)校对集utf8_unicode_ci与utf8_general_ci