概念:WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并被RFC7936所补充规范。
<?php class WebSocketServer { public $ws_server; CONST PORT = 8090; CONST HOST = '0.0.0.0'; CONST ENABLE_STATIC_HANDLER = TRUE; CONST DOCUMENT_ROOT = '/www/wwwroot/swoole'; public function __construct() { $this->ws_server = new swoole_websocket_server(self::HOST, self::PORT); $this->ws_server->on('open', function ($ws_server, $request) { $this->onOpen($ws_server, $request); }); $this->ws_server->on('message', function ($ws_server, $frame) { $this->onMessage($ws_server, $frame); }); $this->ws_server->on('close', function ($request, $response) { $this->onClose($request, $response); }); //因为webSocket继承自 swoole_http_server 所以它也可以作为httpServer $this->ws_server->set([ 'document_root' => self::DOCUMENT_ROOT, 'enable_static_handler' => self::ENABLE_STATIC_HANDLER, ]); $this->ws_server->start(); } //监听webSocket的连接事件 private function onOpen($ws_server, $request) { echo "欢迎客户端 {$request->fd} 连接本服务器 "; } //监听webSocket的消息事件 private function onMessage($ws_server, $frame) { //$frame->data,数据内容,可以是文本内容也可以是二进制数据,可以通过opcode的值来判断 //$frame->opcode,WebSocket的OpCode类型,可以参考WebSocket协议标准文档 //$frame->finish, 表示数据帧是否完整,一个WebSocket请求可能会分成多个数据帧进行发送(底层已经实现了自动合并数据帧,现在不用担心接收到的数据帧不完整) echo "客户端 {$frame->fd} 说:{$frame->data} (opcode:{$frame->opcode},finish:{$frame->finish}) "; $ws_server->push($frame->fd, "我是服务端,我已收到您的消息,您说的是:".$frame->data); } //监听客户端关闭连接事件 private function onClose($ws_server, $fd) { echo "客户端 {$fd} 已关闭连接 "; } } new WebSocketServer();
启动服务:
[root@iz2ze2rkosydwj6j4rmp7hz swoole]# php ws_server.php
浏览器访问:
websocket和http比较:
HTTP、WebSocket 等应用层协议,都是基于 TCP 协议来传输数据的
HTTP:
1,无状态协议。
2,短连接。(Ajax轮询方式或Long poll方式实现“持久连接”状态)
2,被动型。 客户端请求->服务器端响应。服务端不能主动联系客户端,只能有客户端发起。
WebSocket:
它解决了HTTP的这几个难题。
如被动性,当服务器完成协议升级后(HTTP->Websocket),服务端就可以主动推送信息给客户端啦。
就变成了这样,只需要经过一次HTTP请求,就可以做到源源不断的信息传送了。(在程序设计中,这种设计叫做回调,即:你有信息了再来通知我,而不是我傻乎乎的每次跑来问你)
这样的协议解决了同步有延迟,而且还非常消耗资源的这种情况。
那么为什么他会解决服务器上消耗资源的问题呢?
其实我们所用的程序是要经过两层代理的,即HTTP协议在Nginx等服务器的解析下,然后再传送给相应的Handler(PHP等)来处理。
简单地说,我们有一个非常快速的接线员(Nginx),他负责把问题转交给相应的客服(Handler)。
本身接线员基本上速度是足够的,但是每次都卡在客服(Handler)了,老有客服处理速度太慢。,导致客服不够。
Websocket就解决了这样一个难题,建立后,可以直接跟接线员建立持久连接,有信息的时候客服想办法通知接线员,然后接线员在统一转交给客户。
这样就可以解决客服处理速度过慢的问题了。
同时,在传统的方式上,要不断的建立,关闭HTTP协议,由于HTTP是非状态性的,每次都要重新传输identity info(鉴别信息),来告诉服务端你是谁。
虽然接线员很快速,但是每次都要听这么一堆,效率也会有所下降的,同时还得不断把这些信息转交给客服,不但浪费客服的处理时间,而且还会在网路传输中消耗过多的流量/时间。
但是Websocket只需要一次HTTP握手,所以说整个通讯过程是建立在一次连接/状态中,也就避免了HTTP的非状态性,服务端会一直知道你的信息,直到你关闭请求,这样就解决了接线员要反复解析HTTP协议,还要查看identity info的信息。
同时由客户主动询问,转换为服务器(推送)有信息的时候就发送(当然客户端还是等主动发送信息过来的。。),没有信息的时候就交给接线员(Nginx),不需要占用本身速度就慢的客服(Handler)了。
WebSocket 机制
以下简要介绍一下WebSocket的原理及运行机制。
WebSocket是HTML5下一种新的协议。它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的。它与HTTP一样通过已建立的TCP连接来传输数据,但是它和HTTP最大不同是:
WebSocket是一种双向通信协议。在建立连接后,WebSocket服务器端和客户端都能主动向对方发送或接收数据,就像Socket一样;
WebSocket需要像TCP一样,先建立连接,连接成功后才能相互通信。