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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
//创建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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
<!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及开发聊天室很有帮助。
原文链接:http://www.jianshu.com/p/fedbb9d2d999