基于Swoole实现PHP与websocket聊天室


Posted in PHP onAugust 03, 2016

websocket

Websocket只是一个网络通信协议

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

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

WebSocket和HTTP的关系

基于Swoole实现PHP与websocket聊天室

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

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

http和websocket 请求头对比:

基于Swoole实现PHP与websocket聊天室

基于Swoole实现PHP与websocket聊天室

HTTP:

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

WebSocket:

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

http和websocket 响应头对比:

基于Swoole实现PHP与websocket聊天室

基于Swoole实现PHP与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及开发聊天室很有帮助。

PHP 相关文章推荐
PHP4在Windows2000下的安装
Oct 09 PHP
PHP获取163、gmail、126等邮箱联系人地址【已测试2009.10.10】
Oct 11 PHP
PHP在字符断点处截断文字的实现代码
Apr 21 PHP
使用php+Ajax实现唯一校验实现代码[简单应用]
Nov 29 PHP
php中使用preg_match_all匹配文章中的图片
Feb 06 PHP
基于PHP 面向对象之成员方法详解
May 04 PHP
PHP基于GD库的缩略图生成代码(支持jpg,gif,png格式)
Jun 19 PHP
thinkPHP实现表单自动验证
Dec 24 PHP
php操作路径的经典方法(必看篇)
Oct 04 PHP
PHP实现的Redis多库选择功能单例类
Jul 27 PHP
详解php curl带有csrf-token验证模拟提交方法
Apr 18 PHP
在PHP中输出JS语句以及乱码问题的解决方案
Feb 13 PHP
浅析php如何实现App常用的秒发功能
Aug 03 #PHP
php微信开发之带参数二维码的使用
Aug 03 #PHP
PHP支付系统设计与典型案例分享
Aug 02 #PHP
php微信支付接口开发程序
Aug 02 #PHP
比较完整的微信开发php代码
Aug 02 #PHP
微信利用PHP创建自定义菜单的方法
Aug 01 #PHP
php微信浏览器分享设置以及回调详解
Aug 01 #PHP
You might like
基于文本的访客签到簿
2006/10/09 PHP
php include和require的区别深入解析
2013/06/17 PHP
如何在php中正确的使用json
2013/08/06 PHP
linux下安装php的memcached客户端
2014/08/03 PHP
[原创]PHP获取数组表示的路径方法分析【数组转字符串】
2017/09/01 PHP
php二维数组按某个键值排序的实例讲解
2019/02/15 PHP
使用JSLint提高JS代码质量方法分享
2013/12/16 Javascript
限制复选框最多选择项的实现代码
2016/05/30 Javascript
使用jsonp实现跨域获取数据实例讲解
2016/12/25 Javascript
JavaScript实现的仿新浪微博原生态输入字数即时检查功能【兼容IE6】
2017/09/26 Javascript
微信小程序实现折叠展开效果
2018/07/19 Javascript
angularJS实现不同视图同步刷新详解
2018/10/09 Javascript
vue中如何去掉空格的方法实现
2018/11/09 Javascript
ES6入门教程之let、const的使用方法
2019/04/13 Javascript
小程序中的箭头函数的具体使用
2020/06/19 Javascript
[01:19]DOTA2城市挑战赛报名开始 开启你的城市传奇
2018/03/23 DOTA
Python批量修改文件后缀的方法
2014/01/26 Python
Python抓取聚划算商品分析页面获取商品信息并以XML格式保存到本地
2018/02/23 Python
Python处理菜单消息操作示例【基于win32ui模块】
2018/05/09 Python
python爬取个性签名的方法
2018/06/17 Python
python Django编写接口并用Jmeter测试的方法
2019/07/31 Python
python爬虫 2019中国好声音评论爬取过程解析
2019/08/26 Python
Python pathlib模块使用方法及实例解析
2020/10/05 Python
如何用python开发Zeroc Ice应用
2021/01/29 Python
一个不错的HTML5 Canvas多层点击事件监听实例
2014/04/29 HTML / CSS
Onzie官网:美国时尚瑜伽品牌
2019/08/21 全球购物
英国领先的在线礼品店:Getting Personal
2019/09/24 全球购物
小学生班会演讲稿
2014/01/09 职场文书
家长对小学生的评语
2014/01/28 职场文书
开展党的群众路线教育实践活动方案
2014/02/05 职场文书
节约能源标语
2014/06/17 职场文书
事业单位聘任报告
2015/03/02 职场文书
社区重阳节活动总结
2015/03/24 职场文书
工程主管竞聘书
2015/09/15 职场文书
2019个人工作总结
2019/06/21 职场文书
javascript遍历对象的五种方式实例代码
2021/10/24 Javascript