WebSocket学习

Posted 飞鹰学习

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebSocket学习相关的知识,希望对你有一定的参考价值。

概念: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} 连接本服务器\\n";
    }

    //监听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})\\n";
        $ws_server->push($frame->fd, "我是服务端,我已收到您的消息,您说的是:".$frame->data);
    }

    //监听客户端关闭连接事件
    private function onClose($ws_server, $fd)
    {
        echo "客户端 {$fd} 已关闭连接\\n";
    }
}

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一样,先建立连接,连接成功后才能相互通信。

 

以上是关于WebSocket学习的主要内容,如果未能解决你的问题,请参考以下文章

IOS开发-OC学习-常用功能代码片段整理

“未捕获的类型错误:无法在 Websocket Angular JS 上读取未定义的属性‘延迟’”

java SpringRetry学习的代码片段

python 机器学习有用的代码片段

NodeJS中的Websockets。从服务器端WebSocket客户端调用WebSocketServer

学习笔记:python3,代码片段(2017)