SocketIO总结

我在马克飞象上写的一样的内容,感觉那个样式好看的:WorkerMan的部分总结

workerman中部分函数总结

下面是把我搜集到的资料进行了一个整合,具体怎么使用,慢慢摸索吧。

Worker类

中文文档

Connection类

中文文档

SocketIO类

中文文档

Socket类官网例子分析

在WEB消息推送框架官网中他介绍了一个简单的例子,说这个例子简单,我只能呵呵,其中的小心思,细思极恐啊,且听我慢慢道来。

首先来看后端的代码,也就是start.php文件的代码。

<?php
/** 告诉你怎么用这个文件,这个文件不是用浏览器去访问的,而是使用php在本地运行的,像下面这样,注意路径,这里默认运行该命令时,start.php在该路径下: * php start.php start */
/*Worker类的命名空间,至于为什么下面会使用到Worker类,下面再介绍*/
use Workerman\Worker;
// 编译好的自动加载文件,注意路径,一定要加载,否则会报错
include __DIR__ . '/vendor/autoload.php';
// 检测你的环境,该类分windows版本和linux版本的,所以这里是做一个检测
if(strpos(strtolower(PHP_OS), 'win') === 0)
{
    exit("傻逼,你下成了windows版本的,去重新下过!\n");
}

// 标记是全局启动,我也不知道是干嘛的,后来是直接自己写了,就没有用start.php文件了
define('GLOBAL_START', 1);

// 加载IO 和 Web
require_once __DIR__ . '/start_io.php';
require_once __DIR__ . '/start_web.php';

//这里分别说一下上面两个文件,第一个start_io.php,主要的处理文件,所有的请求和处理都是该文件来实现的,也就是我们接下来要重点讲解的文件
//start_web.php是开启了一个web服务,也就是我们常说的apache或者nginx服务器,如果你自己装了web服务器的,那么这个文件也就没有什么用了。

// 运行所有服务,看过Worker类文档的应该都知道这个静态方法的作用了,就是使我们定义的所有Worker类起作用
Worker::runAll();
?>

看过了上面的介绍后,我们就知道,如果我们想要定制自己的特色处理功能,那么重点就是要修改start_io.php。偏偏该部分又不是由一个部分组成的,具体来说是由3部分组成的,这三部分分别是:

  • 客户端的js代码
  • 本地的socket_io.php文件
  • 本地的间接操作socket_io.php的PHP文件

可能有点糊涂了,那么我在这里介绍一下start_io.php的运行顺序,以及如何与另外两个文件配合:

  • 创建一个供客户端连接的socket
$sender_io = new SocketIO(2120);

注意端口号:2120

  • 创建一个供本地PHP文件通信的soket
//先创建,再监听该端口
$inner_http_worker = new Worker('http://0.0.0.0:2121');
$inner_http_worker->listen();

注意端口号:2121

准备工作做好了,接下来就看具体的执行顺序了:

  • 用户端登录相应页面,执行js代码,与后台建立socket通信,具体的js代码如下:

<script src='http://cdn.bootcss.com/socket.io/1.3.7/socket.io.js'></script> <script> // 输入参数格式是:协议://ip地址:端口号 var socket = io('http://127.0.0.1:2120'); // uid是组号 uid = 123; // socket建立,建立后进行登录,并将uid传递回后台 socket.on('connect', function(){ socket.emit('login', uid); }); </script> 

注意js连接的端口号:2120

这里介绍一下uid的作用,我刚开始没想明白,结果被坑了3个小时。
uid是分组的意思,属于同一分组的socket可以统一发送消息,如果一个socket就是一组的话,那么就可以实现根据uid进行单独发送。例子中就是这么想的。

对分组中的用户发送信息
//不包括自己
socket.broadcast.to(uid).emit(‘event_name’, data);
//包括自己
io.sockets.in(uid).emit(‘event_name’, data);

回到js代码上来,这里js代码使用了socket.io.js这个SocketIO类的配套js库代码与后台建立了socket通信。

那么问题来了,当我们想与客户端通信时,只能通过start_io.php文件了,而start_io.php会在命令行中一直执行,那么,当我们想主动与start_io.php管理下的socket通信的话,那么我们该怎么办?或者我们外部人员如何与socket_io.php通信?

解决方法1:

去访问socket_io.php下的socket,然后在socket_io.php中编写对应的代码,这样就可以在外部操作socket_io.php文件中的内容了,也就是等于间接和socket_io.php管理下的客户端通信

缺点:

与客户抢占socket资源,一个socket能处理的连接是有限的,应该尽最大可能预留给客户,所以上述方案是可以实现的,但是欠妥当。

解决方案2:

建立新的socket,专门为本地访问socket_io.php使用,并在socket_io.php中进行监听。这也是官网上那个例子的做法,看后台源码:


$sender_io->on('workerStart', function(){
    // 监听一个http端口
    $inner_http_worker = new Worker('http://0.0.0.0:2121');
    // 当http客户端发来数据时触发
    $inner_http_worker->onMessage = function($http_connection, $data){
       //本地PHP文件触发该socket的该部分功能时执行的代码
        }
    };
    // 执行监听
    $inner_http_worker->listen();
    }

其中,当socket_io.php开始运行后,就会实例化一个Worker类,并在代码中监听该端口,当外部尝试连接该socket后,就会触发Worker类的onMessage回调函数,开始执行后面的function(),那么我们就可以在内部设定相应的操作了。这样就可以实现使用另外的php代码来操作start_io.php下的socket了。

这样做和解决方案1有什么区别呢?首先我们新开了一个socket,专门用来与start_io.php进行通信,也就是2121端口,而客户连接的是2120端口,两者并不冲突,从而也不会影响客户的操作。

缺点:

这个专门用于本地php代码操作start_io.phpsocket不止你可以用,别人也可以用,比如我可以使用上面的js代码自己连接到该端口进行操作,绕过你的php文件,那么可想而知,这绝对是一场灾难,所以一定要在


$inner_http_worker->onMessage = function($http_connection, $data){
       //一定要在这里加入验证,保证外部人员连接时,可以进行辨别
        }
    };

上面都说使用本地php脚本来操作start_io.php文件,却一直没有说具体的方法,下面就来看具体的代码,其实就是使用php的curl函数,与2121端口进行通信,从而间接操作start_io.php

下面是官网上的例子:


<?php
// 指明给谁推送,为空表示向所有在线用户推送
$to_uid = "";
// 推送的url地址,使用自己的服务器地址
$push_api_url = "http://workerman.net:2121/";
$post_data = array(
   "type" => "publish",
   "content" => "这个是推送的测试数据",
   "to" => $to_uid, 
);
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $push_api_url );
curl_setopt ( $ch, CURLOPT_POST, 1 );
curl_setopt ( $ch, CURLOPT_HEADER, 0 );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $post_data );
curl_setopt ($ch, CURLOPT_HTTPHEADER, array("Expect:"));
$return = curl_exec ( $ch );
curl_close ( $ch );
var_export($return);

curl这块我还不熟,所以要我解释上面那段代码的含义还需要一会,现在能确定的是:

  1. 传输的内容被编写在$post_data中
  2. 会以POST的方式将数据发送到2121端口中去

到此为止,SocketIO的例子就介绍完了,可能有点糊涂,所以最好还是自己试试,这毕竟只是我的总结,肯定不如你们自己学习来的好的。

你可能感兴趣的:(SocketIO总结)