当前位置:首页 > PHP教程 > PHP常见问题

基于Swoole实现PHP与websocket聊天室

websocket

websocket只是一个网络通信协议

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

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

websocket和http的关系

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

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

http和websocket 请求头对比:


http:

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

websocket:

客户端通过http(骑马)带着信请求服务器,但同时,携带了upgrade:websocket和connection: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, welcomen"); }); //监听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 closedn"; }); $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及开发聊天室很有帮助。



【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:)!