在workerman中一共内置了5中协议,分别为http、text、frame、websocket和ws,当然你也可以直接使用tcp。
一个一个说。
ProtocolInterface这是workerman为所有协议规定要实现的一个接口(当然你也可以不实现,但是必须实现其中3个方法),此接口定义了三个方法给worker和connection使用。
- input() 用来验证客户端过来的数据是否合法,如果合法就返回其长度。
- decode() 对收到的数据进行解码
- encode() 将要发送的数据进行编码
从这里我们也看到对于一个协议而言,它规定着数据的规则以及数据何时结束。比如input负责结束,decode和encode负责数据的规则。
http这是我们最常用的一个协议了,比如你如果要用workerman实现一个web服务器的功能,这是你需要使用甚至要进行扩展的协议。内置的http实现了基本的内容,比如
- 对常用方法的支持
- 对session \ cookie 的支持
- 对富媒体内容的支持
关于方法workerman内置的http协议支持6种,有GET、POST、PUT、DELETE、HEAD和OPTIONS,我想经常做接口开发的你一定偷偷乐了,起码习惯使用restful的同学会很喜欢。而当你请求的方法非以上六种时,workerman会给你返回一个 HTTP/1.1 400 Bad Request 错误。
另外对于http请求,cookie和session必不可少,workerman在这点上也进行了支持,并且当判断PHP在cli模式下的时候会用HttpCache类来辅助实现session功能。
另外有一点要注意的是,当我们客户端给服务器端发送POST请求的时候,workerman的http协议可以识别请求内容类型为multipart/form-data、application/json和application/x-www-form-urlencoded三种类型。
也就是说表单提交、文件上传和json格式的接口服务,workerman的http都可以正确解析。
text和frametext/frame是两种相对比较简单的协议,我所说的简单是指协议规则,看下面
协议规则
- text 数据包+换行符
- frame 总包长+包体
对于数据包内容并没有太多限制,text/frame只是规定了数据包的边界。
因此当服务器上多个worker进行内部通讯的时候,text/frame是个很好的选择,简单快捷。
另外text/frame对数据包的不限制也决定了其灵活性,当我们做一个应用的时候,你发现使用websocket太麻烦的时候,text/frame是一个很好的选择。
当然你也可以按照text/frame的规范去自定义自己的协议。
websocket 和 ws我想很多人都是因为要实现websocket通讯而选择了workerman,在这点上workerman对其有很好的支持,你只需要如下代码就完成了websocket通讯的服务器端部署。
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
$serverWorker = new Worker("websocket://127.0.0.1:1234");
$serverWorker->count = 1;
$serverWorker->name = "server";
$serverWorker->onMessage = function($connection, $data) {
$connection->send("你好,客户端worker,我收到了。");
};
Worker::runAll();
是不是很简单,只需要指定Worker的通讯协议为websocket,其他就是worker的业务代码了。
而websocket客户端一般是浏览器、小程序等,它们会发起websocket通讯请求,比如下面是一段最简单的websocket在浏览器上的应用。
var ws = new WebSocket("ws://127.0.0.1:1234");
ws.onopen=function(evt){
ws.send("你好,workerman");
};
ws.onmessage=function(evt){
ws.close();
};
ws.onclose=function(evt){
console.log("链接关闭");
};
值得注意的是,当使用H5的WebSocket对象时,对于要请求连接的通讯地址我们需要ws开头。
-----我是分割线-----
突然你的老板说我要用workerman来实现websocket的客户端,小李你去整一整。
这里要告诉你,websocket协议只能用于workerman的服务器端配置,当workerman来实现websocket的客户端的时候,需要用到ws协议。
就必须下面的这段实现代码,我们新建一个worker并在其启动过程中新建tcp链接来模拟websocket。
$worker = new Worker();
$worker->name = 'client';
// 进程启动时
$worker->onWorkerStart = function()
{
$ws_connection = new AsyncTcpConnection("ws://127.0.0.1:1234");
$ws_connection->onConnect = function($connection){
$connection->send('你好服务器端');
};
$ws_connection->onMessage = function($connection, $data){
echo "我是客户端,我收到了服务器端信息,内容是: $data\n";
};
$ws_connection->onError = function($connection, $code, $msg){
echo "error: $msg\n";
};
$ws_connection->onClose = function($connection){
echo "connection closed\n";
};
$ws_connection->connect();
};
要注意的是,当我们使用ws协议让workerman作为websocket客户端的时候,需要使用AsyncTcpConnection来模拟。
小结以上就是workerman内置协议的讲解,更详细的可以看我原创课程,学好协议是我们接下来学习worker类的基础。
共同学习,写下你的评论
评论加载中...
作者其他优质文章