本文首先将对Workerman有一个简单的认知介绍,然后通过我遇到过的一个小项目捋一遍用Workerman来快速实现Socket服务。
1. 知识储备
在开始使用workerman之前,可能需要了解这些:
- 网络通讯协议(HTTP、TCP等)
- 进程和线程
- 了解workerman是什么
- Linux与Windows
- ……
Workerman官方的解释:http://doc.workerman.net/315119
2. Workerman vs Swoole
Swoole是个好东西,拟补了PHP的很多空白,功能上也会比workerman多,C拓展方式性能也没得说,但是就是相比workerman门槛高一点(官方文档不清晰是一方面)。
Workerman纯PHP编写,文档做得很好,上手非常简单,可以快速开发功能,性能也很不错。Workerman还有一个分支项目GatewayWorker,如果项目是长连接并且需要客户端与客户端之间通讯,可以使用GatewayWorker更快速实现功能。
3. 知识概览
WorkerMan中有两个重要的类Worker与Connection。
3.1 Worker类
Workerman中的端口监听通过Worker类实现
Worker类有这么些个回调函数:
- onWorkerStart Worker启动时
- onWorkerReload Worker收到reload信号后
- onConnect 建立链接时(TCP三次握手完成后)触发
- onMessage 客户端通过链接发来数据时(Workerman收到数据时)
- onClose 客户端连接与Workerman断开时
- onBufferFull 超过缓冲区大小限制时
- onBufferDrain 应用层发送缓冲区数据全部发送完毕后
- onError 当客户端的连接上发生错误时
Worker类有这么些个接口:
- runAll 运行所有Worker实例
- stopAll 停止当前进程(子进程)的所有Worker实例并退出
- listen 用于实例化Worker后执行监听
3.2 Connection类
每个客户端连接对应一个Connection对象。
Connection类有这么些个回调函数:
- onMessage 作用与Worker::$onMessage回调相同,区别是只针对当前连接有效
- onClose 此回调与Worker::$onClose回调作用相同,区别是只针对当前连接有效
- onBufferFull 作用与Worker::$onBufferFull回调相同,区别是只针对当前连接起作用
- onBufferDrain 作用与Worker::$onBufferDrain回调相同,区别是只针对当前连接起作用
- onError 作用与Worker::$onError回调相同,区别是只针对当前连接起作用
Connection类有这么些个接口:
- send 向客户端发送数据
- getRemoteIp 获得该连接的客户端ip
- getRemotePort 获得该连接的客户端端口
- close 全的关闭连接
- destroy 立刻关闭连接
- pauseRecv 使当前连接停止接收数据
- resumeRecv 使当前连接继续接收数据
- pipe 将当前连接的数据流导入到目标连接
3.3 其它
- AsyncTcpConnection类
- Timer定时器类
- WebServer
4. 开始实现
4.1 确定需求
首先明确需要做什么,要达到什么目的;以之前做过的一个项目为例,实现一个可以通过APP实时控制的音乐播放系统,大概是以下的模式:
要做到实时推送操作指令达到控制音乐的播放,首先要接收到移动端发来的指令,然后分析,根据指令操纵H5播放器,返回结果,通知移动端。在这里,我们用了WebSocket在浏览器与Server建立了连接来操纵H5播放器,因为移动端不是我们开发,以及这是一个局域网项目,为了使项目更简单,移动端采用了HTTP接口调用的方式(这种方式,在操纵完播放器返回时,我们需要做点手脚,以及会有一定的性能损失),当然最方便最好的就是移动端跟Server建立长连接。
4.2 安装准备
明确了需求,确定了技术方向后,就可以开始干了。虽然workerman有windows版本,不过在windows上是阉割版,能用Linux还是linux。
安装流程:http://doc.workerman.net/315114
windows版本的说明:http://www.workerman.net/windows
4.3 一个简单Server
以WebSocket为例新建一个简单的Server:
1)新建一个项目目录
2)引入workerman(Workerman/Autoloader.php)
require_once ‘/your/path/Workerman/Autoloader.php’;
3)确定协议
目前WorkerMan支持HTTP、Websocket、Text文本协议(WorkerMan中自定义的一个协议,格式为文本+换行),如果需要使用其它协议,可以参照 http://doc.workerman.net/315123 通讯协议一章开发自己的协议。
这里我们以 Websocket 协议为例。
4)编写程序start_websocket.php
一个简单的示例:
<?php
use Workerman\Worker;
require_once __DIR__ . '/path/to/Workerman/Autoloader.php';
// 创建一个Worker监听端口,使用websocket协议通讯
$ws_worker = new Worker('websocket://0.0.0.0:2345');
$ws_worker->count = 1;// 进程数
$ws_worker->name = 'mPlayer';// worker名称
//Worker启动后立即执行的回调函数
$ws_worker->onWorkerStart = function($ws_worker)
{
// ...
};
// 连接建立时触发
$ws_worker->onConnect = function($connection)use($ws_worker)
{
// 设置连接的onMessage回调
$connection->onMessage = function($connection, $data)
{
$connection->send('receive success');
};
// ...
};
// 当收到客户端发来的数据时
$ws_worker->onMessage = function($connection, $data)
{
$connection->send('receive success');
// ...
};
// 如果不是在根目录启动,则运行runAll方法
if(!defined('GLOBAL_START'))
{
Worker::runAll();
}
5)运行Server
Linux下:
以debug(调试)方式启动:php start.php start
以daemon(守护进程)方式启动:php start.php start -d
Windows下:
cmd命令行启动:php start_websocket.php
6)进行测试
进行测试,可以抓包看看请求的状况。
0 条评论
来做第一个留言的人吧!