与硬件设备链接通信(定位设备)git
IM系统(用于直播页面的聊天通信)github
说明:
须要将全部的定位设备实时的接收,将实时的轨迹记录显示在地图上web
注意点:
第一点:
web1服务器 链接的用户1,2,3,web1广播信息时只能广播用户1,2,3,不能广播web2链接的用户4,5,6,假设场景是聊天,用户1发送一消息,只有web1 服务器的用户能看到,web2的用户所有不能收到redis
第二点:消息的频率控制,例:100个设备,100个用户, 100个设备每秒上传一条数据,须要实时广播给每一个用户,就是每秒要100*100 = 1W次,因此能够汇总每秒数据广播给全部用户等等方法数据库
数据传输的流程图:
不包含业务逻辑,将web1,web2,接收的消息汇总而后再广播给web1,web2,再广播给用户服务器
说明:须要把全部的定位设备上传的数据入库,设备7个,每秒一条数据,我的使用swoole 的task 函数(投递一个异步的任务到 task_worker池中,此函数是非阻塞的, worker进程数一样能够配置) 后调用接口方式入库swoole
服务器内存报警问题网络
缘由: 在于swoole_server->task 函数
官方介绍task底层使用Unix Socket管道通讯,是全内存的,没有IO消耗。单进程读写性能可达100万/s,不一样的进程使用不一样的管道通讯,能够最大化利用多核。框架
但这任务若是是调用程序接口时,因为网络的延迟,增长的任务大于消费的任务时,内存占用会不断的增长,致使服务器的内存被占满。异步
解决方法:消息针对入任务的频率控制,能够根据本身的业务场景定义这个时间与是否可延迟等状况,汇总1秒内的全部数据再调用程序接口(汇总时我的使用redis),最好能直接入库,没必要调用接口
简单代码片断,不全(供初学者了解,官方网站demo类似)
function __construct($config) { $this->config = $config; $this->serv = new Swoole\Server($config['server']['host'], $config['server']['port']); // 链接redis $this->redis = new Predis\Client($config['redis']); $this->storage = new Storage($this->config); $this->serv->set([ 'worker_num' => $this->config['server']['workerNum'], //工做进程数量 'daemonize' => $this->config['server']['daemonize'], //是否做为守护进程 'task_worker_num' => $this->config['server']['taskWorkerNum'], ]); $this->serv->on('connect', function ($serv, $fd){ $this->onConnect($fd, $serv); }); $this->serv->on('receive', function ($serv, $fd, $from_id, $data) { $this->onReceive($fd, $serv, $data); }); $this->serv->on('Close', function($server, $fd) { $this->onClose($fd, $server); }); $this->serv->on('Task', function($server, $task_id, $from_id, $data) { $this->onTask($server, $task_id, $from_id, $data); }); $this->serv->on('Finish', function($server, $task_id, $data) { $this->onFinish($server, $task_id, $data); }); $this->serv->start(); } public function onTask($serv, $task_id, $from_id, $data){ // insert 方法是经过接口入库 $this->storage->insert($data); } public function onReceive($fd, $serv, $data) { $this->storage->writeLog('message:'.$data); $data = $this->formatData($data, $fd); $serv->task($data); } public function onClose($fd, $serv) { // writeLog 方法是写入log $this->storage->writeLog('close fd:'.$fd); } public function onFinish($serv, $task_id, $data) { return ''; }
参考官方github: webim系统.
官方wiki: swoole 框架wiki
好处
封装了数据库的model类,数据库的ORM接口
redis的封装,能够实现多实例访问
框架有一些经常使用的方法,像log 等等(我只用到了log)
webim 官方有demon,能够参考
坏处:
文档特别不全,一个简单的实现会折腾半天