首页 php框架 Workerman 基于workerman的实时推送(摒弃ajax轮询)

基于workerman的实时推送(摒弃ajax轮询)

Jan 20, 2020 pm 01:43 PM
workerman

下面由workerman教程栏目给大家介绍实现基于workerman的实时推送,摒弃ajax轮询的方法,希望对需要的朋友有所帮助!

基于workerman的实时推送(摒弃ajax轮询)

先扯些这些内容:

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是一款纯PHP开发的开源高性能的PHP socket 服务器框架。被广泛的用于手机app、移动通讯,微信小程序,手游服务端、网络游戏、PHP聊天室、硬件通讯、智能家居、车联网、物联网等领域的开发。 支持TCP长连接,支持Websocket、HTTP等协议,支持自定义协议。拥有异步Mysql、异步Redis、异步Http、异步消息队列等众多高性能组件。

开始步入正题:为了达到实时通讯,很多时候我们采用了ajax轮询机制,如图:

8a6a3f3a91373e2376d3e9557dc4fa8.png

后面可以采用workerman方式来实现,项目也是tp写的,官方手册这么说到

与其它mvc框架结合建议以上图的方式(ThinkPHP为例):

1、ThinkPHP与Workerman是两个独立的系统,独立部署(可部署在不同服务器),互不干扰。

2、ThinkPHP以HTTP协议提供网页页面在浏览器渲染展示。

3、ThinkPHP提供的页面的js发起websocket连接,连接workerman

4、连接后给Workerman发送一个数据包(包含用户名密码或者某种token串)用于验证websocket连接属于哪个用户。

5、仅在ThinkPHP需要向浏览器推送数据时,才调用workerman的socket接口推送数据。

6、其余请求还是按照原本ThinkPHP的HTTP方式调用处理。

总结:

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

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

619de260e068fef7e4de9ac451916d9.png

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

<script>
    // 连接服务端
    var socket = io(&#39;http://127.0.0.1:2120&#39;);
    // uid可以是自己网站的用户id,以便针对uid推送
    uid = 123;
    // socket连接后以uid登录
    socket.on(&#39;connect&#39;, function(){
    socket.emit(&#39;login&#39;, uid);
    });
    // 后端推送来消息时
    socket.on(&#39;new_msg&#39;, function(msg){
        console.log("收到消息:"+msg);  //自己业务逻辑处理
    });
    
</script>
登录后复制

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

// 指明给谁推送,为空表示向所有在线用户推送
        $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(&#39;workerStart&#39;, function(){
    // 监听一个http端口
    $inner_http_worker = new Worker(&#39;http://0.0.0.0:2121&#39;);
    // 当http客户端发来数据时触发
    $inner_http_worker->onMessage = function($http_connection, $data){
        global $uidConnectionMap;
        $_POST = $_POST ? $_POST : $_GET;
        // 推送数据的url格式 type=publish&to=uid&content=xxxx
        switch(@$_POST[&#39;type&#39;]){
            case &#39;publish&#39;:
                global $sender_io;
                $to = @$_POST[&#39;to&#39;];
                $_POST[&#39;content&#39;] = htmlspecialchars(@$_POST[&#39;content&#39;]);
                // 有指定uid则向uid所在socket组发送数据
                if($to){
                    $sender_io->to($to)->emit(&#39;new_msg&#39;, $_POST[&#39;content&#39;]);
                // 否则向所有uid推送数据
                }else{
                    $sender_io->emit(&#39;new_msg&#39;, @$_POST[&#39;content&#39;]);
                }
                // http接口返回,如果用户离线socket返回fail
                if($to && !isset($uidConnectionMap[$to])){
                    return $http_connection->send(&#39;offline&#39;);
                }else{
                    return $http_connection->send(&#39;ok&#39;);
                }
        }
        return $http_connection->send(&#39;fail&#39;);
    };
    
});
 
if(!defined(&#39;GLOBAL_START&#39;))
{
    Worker::runAll();
}
登录后复制

ok,大功告成!

以上是基于workerman的实时推送(摒弃ajax轮询)的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

实现Workerman文档中的文件上传与下载 实现Workerman文档中的文件上传与下载 Nov 08, 2023 pm 06:02 PM

实现Workerman文档中的文件上传与下载,需要具体代码示例引言:Workerman是一款高性能的PHP异步网络通讯框架,具备简洁、高效、易用等特点。在实际开发中,文件上传和下载是常见的功能需求,本文将介绍如何使用Workerman框架实现文件的上传和下载,并给出具体的代码示例。一、文件上传:文件上传是指将本地计算机上的文件传输至服务器端的操作。下面是使用

如何实现Workerman文档的基本使用方法 如何实现Workerman文档的基本使用方法 Nov 08, 2023 am 11:46 AM

如何实现Workerman文档的基本使用方法简介:Workerman是一个高性能的PHP开发框架,它可以帮助开发者轻松构建高并发的网络应用程序。本文将介绍Workerman的基本使用方法,包括安装和配置、创建服务和监听端口、处理客户端请求等。并给出相应的代码示例。一、安装和配置Workerman在命令行中输入以下命令来安装Workerman:c

swoole和workerman哪个好 swoole和workerman哪个好 Apr 09, 2024 pm 07:00 PM

Swoole 和 Workerman 都是高性能 PHP 服务器框架。Swoole 以其异步处理、出色的性能和可扩展性而闻名,适用于需要处理大量并发请求和高吞吐量的项目。Workerman 提供了异步和同步模式的灵活性,具有直观的 API,更适合易用性和处理较低并发量的项目。

Workerman开发:如何实现基于UDP协议的实时视频通话 Workerman开发:如何实现基于UDP协议的实时视频通话 Nov 08, 2023 am 08:03 AM

Workerman开发:基于UDP协议的实时视频通话摘要:本文将介绍如何使用Workerman框架实现基于UDP协议的实时视频通话功能。我们将深入了解UDP协议的特点,并通过代码示例展示如何搭建一个简单但完整的实时视频通话应用。引言:在网络通信中,实时视频通话是一项非常重要的功能。传统的TCP协议在实现实时性较高的视频通话时,可能会有传输延迟等问题。而UDP

如何使用Workerman搭建高可用性负载均衡系统 如何使用Workerman搭建高可用性负载均衡系统 Nov 07, 2023 pm 01:16 PM

如何使用Workerman搭建高可用性负载均衡系统,需要具体代码示例在现代技术领域中,随着互联网的快速发展,越来越多的网站和应用程序需要处理大量的并发请求。为了实现高可用性和高性能,负载均衡系统成为了必不可少的组件之一。本文将介绍如何使用PHP开源框架Workerman搭建一个高可用性的负载均衡系统,并提供具体的代码示例。一、Workerman简介Worke

如何实现Workerman文档中的定时器功能 如何实现Workerman文档中的定时器功能 Nov 08, 2023 pm 05:06 PM

如何实现Workerman文档中的定时器功能Workerman是一款强大的PHP异步网络通信框架,它提供了丰富的功能,其中就包括定时器功能。使用定时器可以在指定的时间间隔内执行代码,非常适合定时任务、轮询等应用场景。接下来,我将详细介绍如何在Workerman中实现定时器功能,并提供具体的代码示例。第一步:安装Workerman首先,我们需要安装Worker

如何实现Workerman文档中的反向代理功能 如何实现Workerman文档中的反向代理功能 Nov 08, 2023 pm 03:46 PM

如何实现Workerman文档中的反向代理功能,需要具体代码示例简介:Workerman是一款高性能的PHP多进程网络通信框架,提供了丰富的功能和强大的性能,广泛应用于Web实时通讯、长连接服务等场景。其中,Workerman还支持反向代理功能,可以实现服务器对外提供服务时的负载均衡和静态资源缓存等功能。本篇文章将介绍如何使用Workerman实现反向代理功

如何实现Workerman文档中的TCP/UDP通信 如何实现Workerman文档中的TCP/UDP通信 Nov 08, 2023 am 09:17 AM

如何实现Workerman文档中的TCP/UDP通信,需要具体代码示例Workerman是一款高性能的PHP异步事件驱动框架,广泛用于实现TCP和UDP通信。本文将介绍如何使用Workerman实现基于TCP和UDP的通信,并提供相应的代码示例。一、TCP通信创建TCP服务器使用Workerman创建一个TCP服务器十分简单,只需编写如下代码:&lt;?ph

See all articles