基于Swoole实现PHP与websocket聊天室

websocket

Websocket只是一个网络通信协议

就像 http、ftp等都是网络通信的协议;不要多想;

相对于HTTP这种非持久的协议来说,Websocket是一个持久化网络通信的协议;

WebSocket和HTTP的关系

有交集,但是并不是全部。

Websocket只是借用了HTTP的一部分协议来完成一次握手。(HTTP的三次握手,此处只完成一次)

http和websocket 请求头对比:

HTTP:

原来的时候,客户端通过http(骑马)带着信请求服务器,服务器处理请求(写回信),再次通过http(骑马)返回;链接断开;

WebSocket:

客户端通过http(骑马)带着信请求服务器,但同时,携带了Upgrade:websocketConnection:Upgrade(两根管子),服务器如果支持WebSocket协议(有两根管子的接口),使用Websocket协议返回可用信息(丢弃马匹),此后信息的传递,均使用这两个管子,除非有一方人为的将管子切断;若服务器不支持,客户端请求链接失败,返回错误信息;

http和websocket 响应头对比:

websocket和ajax轮询、long poll的区别

首先是 ajax轮询 ,ajax轮询的原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息

场景再现:

客户端:啦啦啦,有没有新信息(Request)

服务端:没有(Response)

客户端:啦啦啦,有没有新信息(Request)

服务端:没有。。(Response)

客户端:啦啦啦,有没有新信息(Request)

服务端:你好烦啊,没有啊。。(Response)

客户端:啦啦啦,有没有新消息(Request)

服务端:好啦好啦,有啦给你。(Response)

客户端:啦啦啦,有没有新消息(Request)

服务端:。。。没。。。。没。。没有

long poll 其实原理跟 ajax轮询 差不多,都是采用轮询的方式,不在论述;

从上面可以看出,轮询其实就是在不断地建立HTTP连接,然后等待服务端处理,可以体现HTTP协议的另外一个特点,被动性。同时,http的每一次请求与响应结束后,服务器将客户端信息全部丢弃,下次请求,必须携带身份信息(cookie),无状态性

Websocket的出现,干净利落的解决了这些问题;

所以上面的情景可以做如下修改。

客户端:啦啦啦,我要建立Websocket协议,需要的服务:chat,Websocket协议版本:17(HTTP Request)

服务端:ok,确认,已升级为Websocket协议(HTTP Protocols Switched)

客户端:麻烦你有信息的时候推送给我噢。。

服务端:ok,有的时候会告诉你的。

客户端:balab开始斗图alabala

服务端:苍井空ala

客户端:流鼻血了,我擦……

服务端:哈哈布尔教育牛逼啊哈哈哈哈

服务端:笑死我了哈哈

Swoole

但是,为了用PHP配合HTML5完成一次WebSocket请求和响应,哥走过千山万水,在密林深处,发现了Swoole :

PHP语言的异步、并行、高性能网络通信框架,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询。

支持的服务:

HttpServer

WebSocket Server

TCP Server

TCP Client

Async-IO(异步)

Task(定时任务)

环境依赖:

仅支持Linux,FreeBSD,MacOS,3类操作系统

Linux内核版本2.3.32以上

PHP5.3.10以上版本

gcc4.4以上版本或者clang

cmake2.4+,编译为libswoole.so作为C/C++库时需要使用cmake

安装:

必须保证系统中有以下这些软件:

php-5.3.10 或更高版本

gcc-4.4 或更高版本

make

autoconf

Swoole是作为PHP扩展来运行的

安装(root权限):

cd swoole

phpize

./configure

make

sudo make install

配置php.ini

extension=swoole.so

想研究Swoole的同学,自己去看手册(虽然写的不好,但是还是能看懂的)

做一个聊天室

服务器端:socket.php

//创建websocket服务器对象,监听0.0.0.0:9502端口
$ws = new swoole_websocket_server("0.0.0.0", 9502);

//监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) {
  $fd[] = $request->fd;
  $GLOBALS['fd'][] = $fd;
  //$ws->push($request->fd, "hello, welcome\n");
});

//监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
  $msg = 'from'.$frame->fd.":{$frame->data}\n";
//var_dump($GLOBALS['fd']);
//exit;
  foreach($GLOBALS['fd'] as $aa){
    foreach($aa as $i){
      $ws->push($i,$msg);
    }
  }
  // $ws->push($frame->fd, "server: {$frame->data}");
  // $ws->push($frame->fd, "server: {$frame->data}");
});

//监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
  echo "client-{$fd} is closed\n";
});

$ws->start();

客户端:Socket.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="msg"></div>
<input type="text" id="text">
<input type="submit" value="发送数据" onclick="song()">
</body>
<script>
  var msg = document.getElementById("msg");
  var wsServer = 'ws://192.168.1.253:9502';
  //调用websocket对象建立连接:
  //参数:ws/wss(加密)://ip:port (字符串)
  var websocket = new WebSocket(wsServer);
  //onopen监听连接打开
  websocket.onopen = function (evt) {
    //websocket.readyState 属性:
    /*
    CONNECTING  0  The connection is not yet open.
    OPEN  1  The connection is open and ready to communicate.
    CLOSING  2  The connection is in the process of closing.
    CLOSED  3  The connection is closed or couldn't be opened.
    */
    msg.innerHTML = websocket.readyState;
  };

  function song(){
    var text = document.getElementById('text').value;
    document.getElementById('text').value = '';
    //向服务器发送数据
    websocket.send(text);
  }
   //监听连接关闭
//  websocket.onclose = function (evt) {
//    console.log("Disconnected");
//  };

  //onmessage 监听服务器数据推送
  websocket.onmessage = function (evt) {
    msg.innerHTML += evt.data +'<br>';
//    console.log('Retrieved data from server: ' + evt.data);
  };
//监听连接错误信息
//  websocket.onerror = function (evt, e) {
//    console.log('Error occured: ' + evt.data);
//  };

</script>
</html>

以上就是基于Swoole实现PHP与websocket聊天室的全部内容,相信本文对大家学习PHP和websocket及开发聊天室很有帮助。

时间: 2016-07-31

详解PHP swoole process的使用方法

引入背景:假如我们每天有10000个订单生成,需要同步到仓储系统中去,以前做法是开启一个crontab去跑这些任务,但是发现总有感觉同步效率低,间隔时间都是分钟级别的. 解决方案测试:我们将同步订单的任务表添加一个hash作为key,作为分发条件,因为mysql中select如果做mod函数是用不到索引的,所以我们自己做随机hash,但是务必不需要范围太大,以免服务器资源不够,方法是根据hashkey投放到不同的进程中进行同步,测试代码如下 <?php /** * Created by PhpS

使用php+swoole对client数据实时更新(一)

如果想对一个列表做实时的更新,传统的做法是采用轮询的方式.以web为例,通过Ajax定时请求服务端然后获取数据显示在页面.这种方式实现简单,缺点就是浪费资源. HTTP1.1新增加了对websocket的支持,这样就可以将被动展示转变为主动通知.也就是通过websocket与服务端保持持久链接,一旦数据发生变化,由server通知client数据有更新,然后再进行刷新等操作.这样就省去了很多不必要的被动请求,节省了服务器资源. 要实现一个webscoket的程序,首先需要使用支持html5的浏览

PHP框架Swoole定时器Timer特性分析

本文所述PHP框架Swoole定时器Timer特性分析具有很好的实用价值,值得PHP程序开发人员学习借鉴.具体分析如下: 首先,在各种业务型系统中,往往需要服务器在后台扫描相关数据,触发相应的统计.通知等操作. 比如对于一个项目管理系统,需要每天的特定时间内,统计每项任务的执行.到期情况.整个项目的进度等等,根据统计情况,做相应通知处理: 这样一个场景,如何编程实现? 用一般的编程方式,是无法实现自动触发与统计的.当然,简单的思路,是利于系统的cron job机制.但这种方式,对于配置及可靠性方

php安装swoole扩展的方法

本文实例讲述了php安装swoole扩展的方法.分享给大家供大家参考.具体如下: 我本机是OS X,想要安装swoole体验一下,于是: 复制代码 代码如下: andy@AndyMacBookPro:/usr/local/webdata/github$ cd swoole-src/ andy@AndyMacBookPro:/usr/local/webdata/github/swoole-src$ git pull Already up-to-date. andy@AndyMacBookPro:/

php异步多线程swoole用法实例

本文实例讲述了php异步多线程swoole用法.分享给大家供大家参考.具体分析如下: swoole重新定义PHP语言的高性能网络通信框架,提供了PHP语言的异步多线程服务,下面的实例就可以证实这一功能. 一般来说,Swoole提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询. swoole以前听过, 拿来做游戏服务器简直是神器-今天稍微的感受了一下,  在 ubuntu 下搭建了

linux平台编译安装PHP7并安装Redis扩展与Swoole扩展实例教程

本文实例讲述了linux平台编译安装PHP7并安装Redis扩展与Swoole扩展的方法.分享给大家供大家参考,具体如下: 前面<PHP7安装Redis扩展教程[Linux与Windows平台]>一文告诉读者简单的安装Redis的方法,下面我们来实现在linux中编译安装PHP7并安装Redis扩展与Swoole扩展的方法. 编译安装PHP7并安装Redis扩展Swoole扩展: 在编译php7的机器上已经有编译安装过php5.3以上的版本,从而依赖库都有了 本php7是编译成fpm-php

使用swoole扩展php websocket示例

复制代码 代码如下: <?phpdefine('DEBUG', 'on');define("WEBPATH", str_replace("\\","/", __DIR__));require __DIR__ . '/../libs/lib_config.php'; class WebSocket extends Swoole\Network\Protocol\WebSocket{    /**     * 下线时,通知所有人     */ 

PHP的swoole扩展安装方法详细教程

Swoole支持PHP 5.3.10以上版本,所以安装Swoole之前请先安装PHP 5.3.10以上版本,现在来介绍Windows下PHP安装配置方法. 软件版本:php-5.3.1-Win32-VC6-x86.zip 这个不需要额外的安装.net的库,所以就用这个了.可以使用其他的. 1.PHP安装 使用绿色方式,下载Zip文件解压. 2.配置 在解压的根目录下找到php.ini-development,是用于开发环境的配置文件:还有一个php.ini-production,这个是用于生产环

PHP+swoole实现简单多人在线聊天群发

由于本文的能力有限,有好多聊天逻辑的细节没有实现,只实现了群发,具体代码如下所示: php代码: $serv = new swoole_websocket_server("127.0.0.1",3999); //服务的基本设置 $serv->set(array( 'worker_num' => 2, 'reactor_num'=>8, 'task_worker_num'=>1, 'dispatch_mode' => 2, 'debug_mode'=>

初识PHP中的Swoole

Swoole是一种PHP高级Web开发框架,框架不是为了提升网站的性能,是为了提升网站的开发效率.最少的性能损耗,换取最大的开发效率.利用Swoole框架,开发一个复杂的Web功能,可以在很短的时间内完成. 官方定义: Swoole:重新定义PHP PHP的异步.并行.高性能网络通信引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询. Swo

初识Java8中的Stream

lambda表达式是stream的基础,初学者建议先学习lambda表达式,http://www.jb51.net/article/121129.htm 1.初识stream 先来一个总纲: 东西就是这么多啦,stream是java8中加入的一个非常实用的功能,最初看时以为是io中的流(其实一点关系都没有),让我们先来看一个小例子感受一下: @Before public void init() { random = new Random(); stuList = new ArrayList<St

在Laravel5.6中使用Swoole的协程数据库查询

什么是Swoole 直接套用Swoole官网的介绍:PHP的异步.并行.高性能网络通信引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询. Swoole内置了Http/WebSocket服务器端/客户端.Http2.0服务器端. Swoole官网的文档不够丰富啊,这比较头疼,但大部分的问题都解释了.如果你对Swoole很感兴趣,那么看看这个S

Java8如何构建一个Stream示例详解

Stream初体验 Stream是Java8中操作集合的一个重要特性,我们先来看看Java里面是怎么定义Stream的: "A sequence of elements supporting sequential and parallel aggregate operations." 我们来解读一下上面的那句话: 1.Stream是元素的集合,这点让Stream看起来用些类似Iterator: 2.可以支持顺序和并行的对原Stream进行汇聚的操作. Stream的创建方式有很多种,除

golang通过context控制并发的应用场景实现

golang 里出现多 goroutine 的场景很常见, 最常用的两种方式就是 WaitGroup 和 Context, 今天我们了解一下 Context 的应用场景 使用场景 场景一: 多goroutine执行超时通知 并发执行的业务中最常见的就是有协程执行超时, 如果不做超时处理就会出现一个僵尸进程, 这累计的多了就会有一阵手忙脚乱了, 所以我们要在源头上就避免它们 看下面这个示例: package main import ( "context" "fmt"

初识 Vue.js 中的 *.Vue文件

什么是Vue.js? vue.js是一套构建用户界面的渐进式框架,它采用自底向上增量开发的设计.(自底向上设计方法是根据系统功能要求,从具体的器件.逻辑部件或者相似系统开始,凭借设计者熟练的技巧和丰富的经验,通过对其进行相互连接.修改和扩大,构成所要求的系统.)Vue 的核心库只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合.另一方面,当与单文件组件和Vue生态系统支持的库结合使用时,Vue 也完全能够为复杂的单页应用程序提供驱动. 什么是*.vue文件 首先,我们用 vue-cli

Vue中UI组件库之Vuex与虚拟服务器初识

一.日历组件 new Date()的月份是从0开始的. 下面表达式是:2018年6月1日 new Date(2018, 5, 1); 下面表达式是:2018年5月1日 new Date(2018, 4, 1); 或 new Date(2018, 5-1, 1); 下面表达式是:2018年5月31日(得到上个月的最后一天) new Date(2018, 5 , 0); 日的参数可以是0,也可以是负数,表示上个月底的那一天. 下面表达式是:2018年7月01日 new Date(2018, 5, 3

关于Curl在Swoole协程中的解决方案详析

前言 众所周知,在 Swoole 应用中,是不推荐使用 Curl 的,因为 Curl 会阻塞进程. 本文会用实际的代码和数据,用最直观的方式,让你明白为什么. 最后还会给出 Curl 在 Swoole 中的解决方案,如果不想看分析可以直接拉到最后. 例程对比 宇润看文章不喜欢那些虚的,所以自己写也比较实在,直接来跑一下代码,用数据看为什么不推荐在 Swoole 使用 Curl. 为了偷懒,我直接用了 YurunHttp的 Curl 和 Swoole Handler,来替代那些又臭又长的 Curl

PHP swoole中使用task进程异步的处理耗时任务应用案例分析

本文实例讲述了PHP swoole中使用task进程异步的处理耗时任务.分享给大家供大家参考,具体如下: 我们知道,swoole中有两大进程,分别是 master 主进程和 manager 管理进程. 其中 master 主进程中会有一个主 reactor 线程和多个 reactor 线程,主要的作用就是用来维护TCP连接,处理网络IO,收发数据. 而 manager 管理进程,作用则是 fork 和管理 worker 和 task 进程. worker 进程的作用是接收 reactor 线程传

PHP swoole中http_server的配置与使用方法实例分析

本文实例讲述了PHP swoole中http_server的配置与使用方法.分享给大家供大家参考,具体如下: swoole中为我们提供了一个swoole_http_server类,方便我们处理http请求. 但是它对http协议的支持并不完整,所以一般建议在前面加一层nginx进行代理,对于php文件的处理交由swoole处理. 一.创建一个简单的http服务 <?php //创建一个http server服务 $server = new swoole_http_server('0.0.0.0'