文档章节

如何在php后端及时推送消息给客户端

d
 dragon_tech
发布于 02/22 09:06
字数 870
阅读 33
收藏 0
PHP
walkor大神,目前需求是这样的:

有一群商家在后台网页处理批量导入产品 -》 服务器接受请求 -》 开始foreach一个一个处理导入请求;

我现在想每成功导入一个就推送到前台显示已经导入成功,直到全部导入自动结束推送。

看了聊天室代码,消息推送都是靠前端js+event.php,我想直接在php里面不需要onMessage触发.

我从下午看到现在文档,也看了很多问答,依然非常糊涂,不奢望给整段代码,但是希望walkor大神给点思路。
2015-08-21 添加评论
分享

36 个回复

 

walkor

赞同来自: vsgeping osacar ivan hnxymjj gzchen 更多 »

后端代码
push.php
<?php
	use Workerman\Worker;
	require_once './Workerman/Autoloader.php';
	// 初始化一个worker容器,监听1234端口
	global $worker;
	$worker = new Worker('websocket://0.0.0.0:1234');
	// 这里进程数必须设置为1
	$worker->count = 1;
	// worker进程启动后建立一个内部通讯端口
	$worker->onWorkerStart = function($worker)
	{
	    // 开启一个内部端口,方便内部系统推送数据,Text协议格式 文本+换行符
	    $inner_text_worker = new Worker('Text://0.0.0.0:5678');
	    $inner_text_worker->onMessage = function($connection, $buffer)
	    {
	        global $worker;
	        // $data数组格式,里面有uid,表示向那个uid的页面推送数据
	        $data = json_decode($buffer, true);
	        $uid = $data['uid'];
	        // 通过workerman,向uid的页面推送数据
	        $ret = sendMessageByUid($uid, $buffer);
	        // 返回推送结果
	        $connection->send($ret ? 'ok' : 'fail');
	    };
	    $inner_text_worker->listen();
	};
	// 新增加一个属性,用来保存uid到connection的映射
	$worker->uidConnections = array();
	// 当有客户端发来消息时执行的回调函数
	$worker->onMessage = function($connection, $data)use($worker)
	{
	    // 判断当前客户端是否已经验证,既是否设置了uid
	    if(!isset($connection->uid))
	    {
	       // 没验证的话把第一个包当做uid(这里为了方便演示,没做真正的验证)
	       $connection->uid = $data;
	       /* 保存uid到connection的映射,这样可以方便的通过uid查找connection,
	        * 实现针对特定uid推送数据
	        */
	       $worker->uidConnections[$connection->uid] = $connection;
	       return;
	    }
	};
	
	// 当有客户端连接断开时
	$worker->onClose = function($connection)use($worker)
	{
	    global $worker;
	    if(isset($connection->uid))
	    {
	        // 连接断开时删除映射
	        unset($worker->uidConnections[$connection->uid]);
	    }
	};

	// 向所有验证的用户推送数据
	function broadcast($message)
	{
	   global $worker;
	   foreach($worker->uidConnections as $connection)
	   {
	        $connection->send($message);
	   }
	}
	
	// 针对uid推送数据
	function sendMessageByUid($uid, $message)
	{
	    global $worker;
	    if(isset($worker->uidConnections[$uid]))
	    {
	        $connection = $worker->uidConnections[$uid];
	        $connection->send($message);
	        return true;
	    }
	    return false;
	}
	
	// 运行所有的worker(其实当前只定义了一个)
	Worker::runAll();


启动后端服务
php push.php start -d

前端接收推送的js代码
var ws = new WebSocket('ws://127.0.0.1:1234');
    ws.onopen = function(){
        var uid = 'uid1';
        ws.send(uid);
    };
    ws.onmessage = function(e){
        alert(e.data);
    };


后端推送消息的代码
// 建立socket连接到内部推送端口
    $client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1);
    // 推送的数据,包含uid字段,表示是给这个uid推送
    $data = array('uid'=>'uid1', 'percent'=>'88%');
    // 发送数据,注意5678端口是Text协议的端口,Text协议需要在数据末尾加上换行符
    fwrite($client, json_encode($data)."\n");
    // 读取推送结果
    echo fread($client, 8192);


这里的uid不一定是用户的id,也可以理解为任务id即 taskid

以上代码亲测可以直接使用

本文转载自:https://wenda.workerman.net/question/508

共有 人打赏支持
d
粉丝 3
博文 283
码字总数 7223
作品 0
西安
私信 提问
MQTT(使用mosquitto做broker)做Android推送部分总结

“读万卷书,行万里路”。我觉得这句话用在程序员的工作中就是:在网络中找一万篇资料,在实践中做一万种尝试。 2014-09-17: 在本文中,由于作者事先不了解,设计不合理,使每个设备采用pre...

Scholer
2014/07/30
0
24
滴滴打车APP和服务器是Http长链接吗?

我有个应用场景需要客户端能够及时收到服务端信息,就是类似滴滴APP一样,司机客户端能够及时收到服务器推送的消息。我想知道服务器和客户端如何通信的。服务器用的什么技术

imjavacoder
2015/02/01
5.4K
4
Java GoEasy 实现服务端推送和Web端推送

项目中需要消息推送,又想降低开发成本。Java服务器端推送,Web端接收推送信息。 具体需求: 需求一:系统框架实现全局异常捕获并录入日志表,实现实时推送消息到客户端页面展示。 需求二:系...

Gibbons
2018/11/17
0
0
详解如何实现在线聊天系统中的实时消息获取

序言 传统web浏览器应用采用客户端主动请求方式,只有在收到浏览器请求时服务端才返回消息,这种模式已经不能满足日益多样化的web应用需求,例如: 在线聊天系统:需要实时获取聊天消息。 实...

中间件小哥
2018/08/08
0
0
三分钟帮你集成极光推送——和那些你可能不知道的事

本文简介:本文前篇,可以帮助朋友们快速集成极光推送。本文后篇,是我自己项目实践的一些总结和心得,应该对读者们还是很有参考价值的,相信读完这篇文章,你会对极光推送有更加深入的理解,...

一只懂音乐的码虫
2018/05/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

如果让你写一个消息队列,该如何进行架构设计?

面试题 如果让你写一个消息队列,该如何进行架构设计?说一下你的思路。 面试官心理分析 其实聊到这个问题,一般面试官要考察两块: 你有没有对某一个消息队列做过较为深入的原理的了解,或者...

李红欧巴
今天
4
0
错题

无知的小狼
今天
2
0
PowerShell因为在此系统中禁止执行脚本的解决方法

参考:window系统包管理工具--chocolatey 报错提示: & : 无法加载文件 C:\Users\liuzidong\AppData\Local\Temp\chocolatey\chocInstall\tools\chocolateyInstall.ps1,因为在此系统上禁止运...

近在咫尺远在天涯
今天
3
0
TP5 跨域请求处理

https://blog.csdn.net/a593706205/article/details/81774987 https://blog.csdn.net/wyk9916/article/details/82315700...

15834278076
今天
3
0
深入理解java虚拟机-Java内存区域与内存溢出异常

深入理解java虚拟机 Java内存区域与内存溢出异常 运行时数据区域 程序计数器 线程私有,内存小,是当前线程执行的字节码行号指示器,字节码解释器通过改变这个计数器的值来选取下一条需要执行...

须臾之余
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部