Linux新建Workerman、composer、redis服务
来源:互联网 发布:淘宝游戏光盘 编辑:程序博客网 时间:2024/06/05 16:31
Linux新建Workerman、composer、redis服务
//by 李居彬
业务场景:用户在微信公众号支付成功后,微信异步回调到java后台,然后java后台给php后台发送支付成功消息,然后php workerman通过socket发送消息通知前端进行语音播报。
整体实现思路:php使用workerman与前端ReconnectingWebSocket保持长连接(端口7272),前端打开WebSocket连接成功后,向workerman发送一条消息(包含了当前场地信息以及type标示),后台收到前端注册消息后,将当前发送者的clientid和场地信息放在redis进行持久化缓存。如果断开连接,在onClose中把当前断开者的clientid从redis中取出这条消息然后删除。Java后台收到微信异步回调消息后记录这条消息的有效性并且调用php接口,将支付方式、商户、场地、金额等信息发送给php后台。Php后台收到消息后开启一个socket客户端(端口6789),通过stream_socket_client发送消息给6789这个服务。重点说明下,为什么php收到消息后不直接发送给7272,而是要发送给6789呢?如果发送给7272,直接通过7272通知前端就可以了,但是实际情况下是无法发送给7272的。无法直接发送给7272的原因,我们的项目是基于thinkphp框架,tp里面无法加载到workerman的协议信息,stream_socket_client无法发送给7272。所以在workerman下新开了一个stream_socket_server的6789。
这样消息发送到6789后asyncTcpconnection异步tcp连接7272把消息再发出去。7272的onMessage中收到消息后,这里面需要处理是前端发送过来的消息还是后台发送过来的消息,如果前端的话则进行redis注册缓存,后台的话则根据officeid从redis中获取到clientid。然后发送给前端,前端收到消息后进行最后一步验证,判断商户及场地信息,防止网络异常情况下发送错消息。所有验证通过后前端就可以语音合成播放了!
一. Linux安装workerman扩展
1.Workerman对php环境要求PHP CLI>=5.4,可以运行命令 php -v查看版本
2. Linux系统要求php安装了posix和pcntl扩展
。如果没有安装,百度查找方法安装。(yuminstall php-process
)
3.curl -Sshttp://www.workerman.net/check.php | php
运行查看是否满足条件。
4、命令行运行yum install php-cli php-process git gcc php-devel php-pear libevent-devel-y
5、命令行运行pecl install event注意提示:Include libevent OpenSSL support [yes] : 时输入no回车,其它直接敲回车就行
6、命令行运行echo extension=event.so > /etc/php.d/event.ini
7、命令行运行git clonehttps://github.com/walkor/Workerman
8. 将下载https://github.com/walkor/workerman-chat.git的包放在workerman的Application目录下
二. 配置Composer
1. 在你的个人目录下面新建一个composer的文件
2. 然后cd 到composer目录下
3. 下载安装程序php –r "copy('https://getcomposer.org/installer','composer-setup.php');"
4. ls
5. 安装程序验证php -r "if (hash_file('SHA384', 'composer-setup.php') ==='55d6ead61b29c7bdee5cccfb50076874187bd9f21f65d8991d46ec5cc90518f447387fb9f76ebae1fbbacf329e583e30'){ echo 'Installer verified'; } else { echo 'Installer corrupt';unlink('composer-setup.php'); } echo PHP_EOL;"
6. 运行安装程序php composer-setup.php
7. 删除安装文件
8. ls
9. php-r "unlink('composer-setup.php');"
10.设置环境变量 vim/etc/profile
11.在最后一行加入exportPATH="$PATH:/home/composer"
12.配置中国镜像区composerconfig -g repo.packagist composer https://packagist.phpcomposer.com
13.如果12配置不成功则使用。或者下载特别慢是因为镜像文件走的国外,可自行修改。
14.在全局 composerconfig -g repo.packagist composer https://packagist.phpcomposer.com
15.cd 到Workerman目录下在composer.json同级目录下运行composer update 更新workerman所需要的库文件。
三. 配置Server层
1.如果使用的thinkphp框架,可以将Workerman放到application下和Admin、Home同级目录。如果不使用tp的话,直接放在apache下面就可以了。
2.Chat目录下start_gateway.php是我们要使用的协议端口。
3.在命令行中开启服务。启动方式分两种一个是debug和daemonize。如果测试的话使用debug会在命令行中输入测试内容,关闭窗口即停止服务。正式的话使用daemonize,表示是否以daemon(守护进程)方式运行。如果启动命令使用了 -d参数,则该属性会自动设置为true。也可以代码中手动设置,如果不设置,并且是以守护进程方式运行,则所有终端输出全部重定向到/dev/null。php start.php start –d(debug不用-d)
4. 启动 以debug(调试)方式启动 php start.php start
启动 以daemon(守护进程)方式启动php start.php start –d
Gateway::$stdoutFile = '/dev/stdout.log';在start_getway.php下定义输出内容。
停止 php start.php stop
重启 php start.php restart
平滑启动 php start.php reload(平滑重启不同于普通的重启,平滑重启可以做到在不影响用户的情况下重启服务,以便重新载入PHP程序,完成业务代码更新。)
查看状态 php start.php status
5.开发人员只需要操作Workerman下面的Application自己模块里面的Events.php文件即可,其他文件不要乱动。
四. 配置Client(前端)层
1. 前端websocket连接。
$(document).ready(function(){
var wsurl ="ws://182.92.101.206:7272/";
console.log(wsurl);
var websocket = newWebSocket(wsurl);
websocket.onopen = function(evt){
console.log('Server: 打开WebSocket连接');
};
websocket.onclose = function(evt){
console.log('Server: 关闭WebSocket连接');
};
websocket.onmessage = function(evt){
// var res = JSON.parse(evt);
console.log('Server: 收到消息(来自:'+evt+'请求)');
console.log(evt);
};
websocket.onerror = function(evt){
console.log('Server: 出现错误');
console.log(evt.data);
}
function doSend(msg){
console.log('Client: 发送消息 ' + msg);
websocket.send(msg);
}
$("#getTest").click(function(){
var msg = {'officeid':officeid};
doSend(JSON.stringify(msg));
});
});
五. 后台接口配置层(后台接口收到微信通知后主动向前端发起通讯)
1. 在收到java后台发来的请求时,进行php模拟客户端
$client =stream_socket_client('tcp://127.0.0.1:6789', $errno, $errmsg, 1);
// 推送的数据,包含uid字段,表示是给这个uid推送
//$data= array('uid'=>'uid1', 'percent'=>'88%');
// 发送数据,注意5678端口是Text协议的端口,Text协议需要在数据末尾加上换行符
fwrite($client, '"loginloginloginloginloginloginlogin>>>>>>>>>>>>"'."\n");
// 读取推送结果
echo fread($client, 8192);
2. 在Events.php里面要进行模拟socket的Server层。
$socket = stream_socket_server("tcp://0.0.0.0:6789",$errno, $errstr);
if(!$socket) {
echo "$errstr ($errno)<br />\n";
} else {
while ($conn =stream_socket_accept($socket)) {
echo'<<<<<<<<<>>>>>>>>>>>';
Gateway::sendToAll("login《》《》《》《》《》");
// $gateway= new Gateway("Websocket://0.0.0.0:7272");
// $gateway->sendToAll("loginloginloginloginloginloginlogin>>>>>>>>>>>>");
fwrite($conn, 'The local time is ' . date('n/j/Y g:i a') . "\n");
fclose($conn);
}
fclose($socket);
六. 服务器端协议通讯
1. php前端逻辑同上一步。
2. workerman和php前端通讯需要进行协议链接通讯,tcp无法直接向workerman的websocket端口发送数据请求。那么首先我们要确定一个协议
3. 首先在Workerman/Applications/Chat下新建一个Protocols文件夹
4. 在rotocols一个协议类,JsonNL.php 命名空间为Protocols
5. namespaceProtocols;
class JsonNL
{
/**
* 检查包的完整性
* 如果能够得到包长,则返回包的在buffer中的长度,否则返回0继续等待数据
* 如果协议有问题,则可以返回false,当前客户端连接会因此断开
* @param string $buffer
* @return int
*/
public static functioninput($buffer)
{
// 获得换行字符"\n"位置
$pos = strpos($buffer,"\n");
// 没有换行符,无法得知包长,返回0继续等待数据
if($pos===false)
{
return 0;
}
// 有换行符,返回当前包长(包含换行符)
return $pos+1;
}
/**
* 打包,当向客户端发送数据的时候会自动调用
* @param string $buffer
* @return string
*/
public static functionencode($buffer)
{
// json序列化,并加上换行符作为请求结束的标记
return json_encode($buffer)."\n";
}
/**
* 解包,当接收到的数据字节数等于input返回的值(大于0的值)自动调用
* 并传递给onMessage回调函数的$data参数
* @param string $buffer
* @return string
*/
public static functiondecode($buffer)
{
// 去掉换行,还原成数组
return json_decode(trim($buffer),true);
}
}
6. 新建一个start_phpserver.php,必须为start开头,与start_gateway.php同级别。
7. use \Workerman\Worker;
8. use \Workerman\WebServer;
9. use \GatewayWorker\Gateway;
10. use\GatewayWorker\BusinessWorker;
11. use \Workerman\Autoloader;
12. useWorkerman\Connection\AsyncTcpConnection;
13.
14. $worker = newWorker('JsonNL://0.0.0.0:6789');
15. $worker->onMessage =function($connection, $data)
16. {
17. //建立本地7272端口的异步连接
18. $con = newAsyncTcpConnection('ws://127.0.0.1:7272');
19. $con->connect();
20. $con->send(json_encode($data));
21. $con->close();
22. };
23.
24. if(!defined('GLOBAL_START'))
25. {
26. Worker::runAll();
27.}
28.在start_phpserver.php中新建JsonNL协议链接。
29.在onMessage中进行7272 的websocket通讯。
30.onMessage收到接口请求过来的数据后,然后通过异步连接将消息发送给websocket,然后通过websocket发送给前端。
31.Events.php中的onMessage方法中收到了消息,然后Gateway::sendToAll($message);发送给前端。
七. 启动服务(放在最后一步)
php start.php start
八. 将链接的客户端信息进行redis缓存(异步redis)
1. 服务器搭建redis环境。
2. 在usr目录下下载redis源码wget http://download.redis.io/releases/redis-2.8.3.tar.gz
3. tarxzf redis-2.8.3.tar.gz
4. cd redis-2.8.3
5. make
6. src/redis-server启动服务
7. 测试是否成功
8. redis-cli
9. setfoo bar
10.getfoo
11.源文件没用的话可以删除掉。
12.ps-ef|grep 6397查看redis端口
13.在src/redis-cli下输入info可以查看redis的所有信息。
14.vimphp.ini 加上extension = redis.so
15.如果安装扩展失败,或者启用时提示失败。可以安装phpredis 命令:pecl install redis
16.安装后的提示。
Buildprocess completed successfully
Installing'/usr/lib64/php/modules/redis.so'
installok: channel://pecl.php.net/redis-3.1.2
configurationoption "php_ini" is not set to php.ini location
You should add "extension=redis.so" to php.ini
提示要注意下,注意检查。Phpinfo()中应该可以看到redis服务了。
[root@redis_01redis]# vim sentinel.conf
daemonize yes
logfile"/var/log/sentinel_log.log"
[root@redis_01 redis]# redis-server/etc/redis/sentinel.conf --sentinel
[root@redis_01 redis]# cat/var/log/sentinel_log.log
正式服务器redis服务在usr/redis/redis-3.2.9/src/redis-server启动,默认启动了进程守护需要重启的话,可以通过查看进程然后kill 再重新运行。
netstat -apn | grep 6379
ps –aux
lsof -i:6379
17.常用redis整理。
1.【 sadd key vaule 】 往集合中插入一个元素,如果value值已存在集合中,则返回0,不会被重复插入。
2.【 sinter key1 key2 ... keyN 】 取出n个key之间的交集。比如 key1里面有值a,b,c,d,e,key2里面有d,e,f,sinterkey1 key2返回d,e。
3.【 sunion key1 key2 ... keyN 】 取出n个key之间的并集。比如 key1里面有值a,b,c,d,e,key2里面有d,e,f,sunionkey1 key2返回a,b,c,d,e,f。
4.【 sdiff key1 key2 】 取出n个key之间的差集。比如 key1里面有值a,b,c,d,e,key2里面有d,e,f,sdiffkey1 key2返回a,b,c;反过来sdiff key2key1返回f。
5.【 smembers key 】 返回key集合中所有的元素,结果是无序的。
6.【 sismember key value 】 查看value这个值是否在key集合中。存在返回1,不存在返回0。
7.【 scard key 】 返回集合中有多少个元素。
8.【 smove key1 key2 value 】 把value从key1中移到key2中去。
9.【 srem key value1 value2 ... valueN 】 从key集合中删掉某些元素。
- Linux新建Workerman、composer、redis服务
- linux 新建tomcat服务
- workerman-chat linux安装
- linux新建weblogic服务流程
- Linux安装Redis服务
- linux Redis 注册服务
- Linux之redis服务
- Linux安装Redis服务
- linux安装redis服务
- Linux安装redis服务
- 续安装好composer和workerman之后;TP5运行workerman的操作
- Workerman
- Workerman
- workerman
- Workerman
- thinkphp让workerman 跑起来, 新建一个workerman,怎么跑起来windows下
- linux系统redis服务配置
- linux centos搭建redis服务
- 开挂人生的启程
- BZOJ3531: [Sdoi2014]旅行
- 机器学习入门第一天,自己对数值预测算法的理解
- DQN从入门到放弃学习总结(2)
- HNUSTOJ-1689 送外卖(TSP问题)
- Linux新建Workerman、composer、redis服务
- 《西瓜书》笔记10:降维与度量学习(三)
- HDU-Gameia
- 列表(list)
- 实现图片通过滚轮的放大缩小
- javaScript内置对象Boolean
- 180度vr直播用,鱼眼视频展开到全景
- SQLite3性能深入分析
- leetcode --19. Remove Nth Node From End of List