消息中心php,PHP实时消息推送,你会不会用workerman

TCP/IP

TCP/IP是个协议组,可分为三个层次:网络层、传输层和应用层。

在网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。

在传输层中有TCP协议与UDP协议。

在应用层有:

TCP包括FTP、HTTP、TELNET、SMTP等协议

UDP包括DNS、TFTP等协议

短连接

连接->传输数据->关闭连接

HTTP是无状态的,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。

也可以这样说:短连接是指SOCKET连接后发送后接收完数据后马上断开连接。

长连接

连接->传输数据->保持连接 -> 传输数据-> 。。。 ->关闭连接。

长连接指建立SOCKET连接后不管是否使用都保持连接,但安全性较差。

http的长连接

HTTP也可以建立长连接的,使用Connection:keep-alive,HTTP 1.1默认进行持久连接。HTTP1.1和HTTP1.0相比较而言,最大的区别就是增加了持久连接支持(貌似最新的 http1.0 可以显示的指定 keep-alive),但还是无状态的,或者说是不可以信任的。

什么时候用长连接,短连接?

长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况,。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。

而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。

总结:

把Workerman作为一个可以向浏览器推送的通道,仅仅在需要向浏览器推送数据时才调用Workerman接口完成推送。业务逻辑全部在ThinkPHP中完成。

ok,到这里,把workerman容器跑起来,注意这里是CLI模式运行

364bdde8bab29fd186bde8457f4ad7ad.png

然后再我们项目接收信息中这么写,附上代码

// 连接服务端

var socket = io('http://127.0.0.1:2120');

// uid可以是自己网站的用户id,以便针对uid推送

uid = 123;

// socket连接后以uid登录

socket.on('connect', function(){

socket.emit('login', uid);

});

// 后端推送来消息时

socket.on('new_msg', function(msg){

console.log("收到消息:"+msg); //自己业务逻辑处理

});

接着,我们在用户向用户发送信息的时候添加

// 指明给谁推送,为空表示向所有在线用户推送

$to_uid = "123";

// 推送的url地址

$push_api_url = "http://127.0.0.1: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);

其中,workerman里面的推送核心代码实现

// 全局数组保存uid在线数据

$uidConnectionMap = array();

// 记录最后一次广播的在线用户数

$last_online_count = 0;

// PHPSocketIO服务

$sender_io = new SocketIO(2120);

// 客户端发起连接事件时,设置连接socket的各种事件回调

// 当$sender_io启动后监听一个http端口,通过这个端口可以给任意uid或者所有uid推送数据

$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){

global $uidConnectionMap;

$_POST = $_POST ? $_POST : $_GET;

// 推送数据的url格式 type=publish&to=uid&content=xxxx

switch(@$_POST['type']){

case 'publish':

global $sender_io;

$to = @$_POST['to'];

$_POST['content'] = htmlspecialchars(@$_POST['content']);

// 有指定uid则向uid所在socket组发送数据

if($to){

$sender_io->to($to)->emit('new_msg', $_POST['content']);

// 否则向所有uid推送数据

}else{

$sender_io->emit('new_msg', @$_POST['content']);

}

// http接口返回,如果用户离线socket返回fail

if($to && !isset($uidConnectionMap[$to])){

return $http_connection->send('offline');

}else{

return $http_connection->send('ok');

}

}

return $http_connection->send('fail');

};

});

if(!defined('GLOBAL_START'))

{

Worker::runAll();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值