1.在根目录下新建Worker目录 进入新建的Worker文件夹 运行 LINUX下运行 composer require workerman/workerman win 下运行 composer require workerman/workerman-for-win

2.Worker文件夹 下新建文件push.php

<?php
//require_once __DIR__ .'/vendor/autoload.php';
require_once __DIR__ .'/vendor/workerman/workerman/Autoloader.php';
// require_once __DIR__ .'/vendor/workerman/workerman-for-win/Autoloader.php'; WIN下的引用
use Workerman\Worker;
//
// 初始化一个worker容器,监听1234端口
$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();

3.controllers 下添加PushController.php

<?php
namespace backend\controllers; use Yii;
use yii\web\Controller; class PushController extends Controller
{
/**
* Renders the index view for the module
* @return string
*/
public function actionWorker()
{
// 建立socket连接到内部推送端口
$client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1);
// 推送的数据,包含uid字段,表示是给这个uid推送
echo 'ERRER:'.$errno.'='.$errmsg;
$data = array('uid'=>'uid1', 'percent'=>'88%测试');
// 发送数据,注意5678端口是Text协议的端口,Text协议需要在数据末尾加上换行符
fwrite($client, json_encode($data)."\n");
// 读取推送结果
echo '$client=='.$client;
echo fread($client, 8192); //return $this->render('index');
}
}
4.前端测试test.html
<!DOCTYPE html>
<html> <head lang="en">
<meta charset="utf-8">
<title></title>
</head> <body>
<h3>WebSocket协议的客户端程序</h3>
<button id="btConnect">连接到WS服务器</button>
<button id="btSendAndReceive">向WS服务器发消息并接收消息</button>
<button id="btClose">断开与WS服务器的连接</button>
<div id="val"></div>
<script type="text/javascript">
var wsClient=null;
btConnect.onclick=function(){
wsClient=new WebSocket('ws://127.0.0.1:1234'); //这个端口号和容器监听的端口号一致
console.log(wsClient)
wsClient.onopen = function(){
var uid = 'uid1';
// 表名自己是uid1
wsClient.send(uid);
console.log('ws客户端已经成功连接到服务器上')
}
wsClient.onmessage = function(e){
console.log('ws客户端收到一个服务器消息:'+e.data);
val.innerHTML=e.data;
}
}
btSendAndReceive.onclick = function(){
wsClient.send('Hello Server');
wsClient.onmessage = function(e){
console.log('ws客户端收到一个服务器消息:'+e.data);
val.innerHTML=e.data;
}
}
btClose.onclick = function(){
wsClient.close();
wsClient.onclose = function(){
console.log('到服务器的连接已经断开');
}
}
</script>
</body>
</html>

4. 模拟过程

  在终端里执行php push.php start -d, 开启服务, 等待客户端(浏览器和php客户端)连接

.浏览器里打开test.html, 打开控制台console, 点击按钮->链接到websocket


 
客户端接收到php推送的消息

另开一个终端, 执行php PushController中的actionWorker方法或者浏览器访问该地址, 此时再客户端就能看到php推送过来的消息, 从而完成一次交互

 
.随后接收到服务器返回消息



 .可以使用多个客户端, 将uid改成uid2, 模拟多个用户

windows上Yii2使用workerman整套流程的更多相关文章

  1. Windows 下 LaTeX 手动安装宏包(package)以及生成帮助文档的整套流程

    本文简单介绍如何手动安装一个 LaTeX 宏包. 一般来说,下载的 TeX 发行版已经自带了很多宏包,可以满足绝大部分需求,但是偶尔我 们也可能碰到需要使用的宏包碰巧没有安装的情况,这时我们就需要自己 ...

  2. 参与github上开源项目的大致流程和注意事项

    Foreword github是一个很火的代码托管服务网站,可能好多人都想参与一两个项目玩一玩学习一下,但由于是纯英文的网站,可能又会止步于想法上没有动手实践.接下来我就介绍一下参与github上开源 ...

  3. 写一个Windows上的守护进程(6)Windows服务

    写一个Windows上的守护进程(6)Windows服务 守护进程因为要开机启动,还要高权限,所以我就把它做成Windows服务了. 关于Windows服务的官方文档,大家可以看https://msd ...

  4. cocos2dx 在windows上实现键盘输入

    cocos2d主要面向的是触摸屏幕设备的,在WINDOWS下的定位感觉多多少少就是相当于一个模拟器,因此并没有太多的PC下重要的键盘支持.然而响应键盘消息对于调试来说可以提供不少方便.下边就通过更改c ...

  5. 在Windows上使用Let加密IIS

    在Windows上使用Let加密IIS https://weblog.west-wind.com/posts/2016/Feb/22/Using-Lets-Encrypt-with-IIS-on-Wi ...

  6. 一步步实现windows版ijkplayer系列文章之六——SDL2源码分析之OpenGL ES在windows上的渲染过程

    一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...

  7. (转)Windows上使用CMake

    CMake简介 原文:http://blog.gclxry.com/use-cmake-on-windows/ 你或许听过好几种 Make 工具,例如 GNU Make ,QT 的 qmake ,微软 ...

  8. 如何在 Windows 上 使用 ONLYOFFICE 协作编辑文档

    ONLYOFFICE Document Server提供文档协作的服务功能,支持Word,Excel和PowerPoint的协作.但是这里告诉我们,需要进行文档管理和存储的二次开发. Please n ...

  9. qt-qml移动开发之在ios上开发和部署app流程简单介绍

    qt5.3已经全面支持移动开发,除了mac,windows,linux.还支持ios,android,wp,meego等移动平台,本教程是作者依据自己的经验,从头讲怎么样在ios上公布自己的app.因 ...

  10. jenkins在windows上自动化部署.Net(.Net Core)项目

    前言 什么是持续集成呢?Continuous integration(CI).持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员至少集成一次,也就意味着每天可能会发生多次集成. ...

随机推荐

  1. Vulnhub:mhz_c1f靶机

    kali:192.168.111.111 靶机:192.168.111.197 信息收集 端口扫描 nmap -A -v -sV -T5 -p- --script=http-enum 192.168. ...

  2. MSF后渗透常用命令

    一.在meterpreter命令行下常用的操作 ps # 查看当前活跃进程 migrate pid # 将Meterpreter会话移植到进程数位pid的进程中 execute -H -i -f cm ...

  3. Head First Python(第2版)书籍 重视大脑的学习指南

    Head First Python(第2版)PDF高清版书籍免费下载地址 提取码:08eo 内容简介  · · · · · · 你想过可以通过一本书就学会Python吗?<Head First ...

  4. flask相关

    app使用flask_session pip install flask_session from flask_session import Session app = Flask(__name__) ...

  5. vue 从后往前循环数组的简洁写法

  6. 蓝牙mesh组网实践(手机配网例程改低功耗)

    目录 在22年7月版本的CH583EVT更新之后,582芯片的adv_vendor_self_provision_with_peripheral例程,适配了wch mesh手机app,支持了OTA,成 ...

  7. 简单的关键词查找实验(基于C语言)

    准备 书名数据库的阵列表示 关键字 书籍 B1 B2 B3 B4 B5 B6 B7 algebra 1 1 1 1 1 1 0 application 1 0 1 1 1 1 0 elementary ...

  8. Flink任务自定义个性化配置logback.xml文件

    之前已经写过如何使用logback将日志直接写入Kafka,然后通过es和kibana实时查看 但是如果我们想要每个任务都能够带上单独的信息比如开发者.任务名称等信息,那么就需要每个任务都指定一个lo ...

  9. Vue: 单页面应用如何保持登录状态

    这篇文章写的还可以 https://www.xiabingbao.com/post/vue/vue-keep-logininfo.html

  10. props其他-混入mixin-插件-elementui使用-localStorage系列-vueRouter-vuex

    目录 props其他-混入mixin-插件-elementui使用-localStorage系列-vueRouter-vuex 今日内容概要 今日内容详细 1 props其他 2 混入mixin 3 ...