首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >腾讯云CDN支持WebSocket

腾讯云CDN支持WebSocket

原创
作者头像
yaho
发布于 2020-05-02 06:25:48
发布于 2020-05-02 06:25:48
24.9K00
代码可运行
举报
文章被收录于专栏:CDN杂谈CDN杂谈
运行总次数:0
代码可运行

1. WebSocket简介

Websocket是用于服务端主动向客户端推送消息的技术。传统的HTTP/HTTPS只能由客户端向服务端发起请求,服务端对请求一一响应。在需要获取服务端状态变化的场景下,如:提交的后台任务是否执行成功,只能通过客户端轮询向服务端发起请求,不仅效率低,还浪费资源(HTTP1.0下每次轮询都需要经过TCP三次握手重新建立连接)。而WebSocket的出现较好的解决了这个问题,在TCP首次建立完连接之后,该连接不自动关闭,在有效期内客户端可以继续向服务端发送消息,服务端也能主动给客户端发送消息。

2. 腾讯云CDN对WebSocket的支持

腾讯云CDN依靠全球广泛部署的CDN节点,高效的网络存储优化方案和精准的调度策略,有效提升下载速度、降低响应时间,提供流畅的用户体验。腾讯云CDN节点自研服务器在提供静态资源访问的能力下,同时支持WebSocket访问,兼容动态资源的极速上云服务。本文将介绍如果验证腾讯云CDN节点支持WebSocket。

2.1 配置源站支持WebSocket

由于WebSocket属于动态资源,不适用于缓存服务,所有请求必定回源,所以首先需要源站支持WebSocket。以下以Python+Nginx为例介绍如何配置代理支持WebSocket。

  • 2.1.1 Websocket服务端

服务端示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/usr/bin/python
#coding=utf8
"""
# Created Time : 2020-05-02 11:07:02

# File Name: websocket-server.py
# Description:

"""
import socket
import base64
import hashlib
import struct
from threading import Thread
 
 
def parse_headers(data):
    headers = {}
    method = url = protocol = ''
    raw_headers = data.split('\r\n\r\n')[0].split('\r\n')
    for i in range(0, len(raw_headers)):
        if i == 0:
            elements = raw_headers[i].split(' ')
            if len(elements) == 3:
                method, url, protocol = elements
        else:
            k, v = raw_headers[i].split(':', 1)
            headers[k] = v.strip()
    print headers
    return method, url, protocol, headers

def calc_sign(data):
    message = data + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'   #不要问为什么是这个字符串,rfc6455中定义的!
    return base64.b64encode(hashlib.sha1(message).digest())
    
def encode(data):
    token = b"\x81"
    length = len(data)
    if length < 126:
        token += struct.pack("B", length)
    elif length <= 0xFFFF:
        token += struct.pack("!BH", 126, length)
    else:
        token += struct.pack("!BQ", 127, length)
 
    return token + data

def decode(raw_data):
    payload_len = ord(raw_data[1]) & 127
    if payload_len == 126:
        extend_payload_len = raw_data[2:4]
        mask = raw_data[4:8]
        decoded = raw_data[8:]
    elif payload_len == 127:
        extend_payload_len = raw_data[2:10]
        mask = raw_data[10:14]
        decoded = raw_data[14:]
    else:
        extend_payload_len = None
        mask = raw_data[2:6]
        decoded = raw_data[6:]
 
    data = bytearray()
    for i in range(len(decoded)):
        chunk = ord(decoded[i]) ^ ord(mask[i % 4])
        data.append(chunk)
    return str(data)

def handle_request(conn):
    data = conn.recv(1024)
    print data
    method, url, protocol, headers = parse_headers(data)
    response = "HTTP/1.1 101 Switching Protocols\r\n" \
                   "Upgrade:websocket\r\n" \
                   "Connection:Upgrade\r\n" \
                   "Sec-WebSocket-Accept:%s\r\n" \
                   "WebSocket-Location:ws://%s%s\r\n\r\n" % (calc_sign(headers['Sec-WebSocket-Key']), headers['Host'], url)
    conn.send(response)
 
    while True:
        try:
            raw_data = conn.recv(1024)
        except Exception as e:
            raw_data = None
        if not raw_data:
            break
        data = decode(raw_data)
        print('recv data', data)
        if not conn.send(encode(data)):
            break
 
 
def run():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(('0.0.0.0', 8888))
    sock.listen(10)
    
    while True:
        conn, address = sock.accept()
        print('new client %s:%s' % address)
        Thread(target=handle_request, args=(conn,)).start()
 
    sock.close()
 
if __name__ == '__main__':
    run()

该服务通过socket响应客户端连接,打印出每个连接的头部,读取客户端发送的消息,并将其发回给客户端。注意websocket通信发送的不是原始消息,需要经过编码,如encode,decode函数。

  • 2.1.2 Websocket客户端

客户端同样需要编解码,也可以直接利用现有工具简化测试步骤:https://pypi.org/project/websocket_client/

  • 2.1.3 本地测试

分两次分别发送两次消息,123和456。

请求的抓包HTTP头部内容如下:

tcpdump抓包
tcpdump抓包
HTTP请求+响应头部
HTTP请求+响应头部

可以看到服务端总共只收到了一个TCP建立连接请求,一组HTTP头部,两组消息共用一个连接。websocket实际上发送和响应的也是标准的http头部格式,只是额外带上了鉴权头部。

  • 2.1.4 配置Nginx代理WebSocket

一般我们会在最终的服务前面挂一个代理服务支持路由+负载均衡等,如Nginx等。Nginx需要启用额外配置支持Websocket,修改Nginx配置文件配置如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    resolver 119.29.29.29;

    # websocket
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }
    upstream websocket {
        server 127.0.0.1:8888;
    }

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       80;
        server_name  _;
        root /usr/local/nginx/nginx/http/;
        access_log  logs/all-http.log;

            # websocket
        location ~ ^/websocket {
            proxy_pass http://websocket;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For
            $proxy_add_x_forwarded_for;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
        }

    }
}

重启nginx服务:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
nginx -s reload

客户端重新请求80端口即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
wsdump.py ws://127.0.0.1:80/websocket

  • 2.1.5 测试CDN支持WebSocket

在腾讯云CDN控制台域名配置页面将域名源站设置为支持websocket的源站,待配置生效后,直接通过WebSocket协议访问。

CDN访问
CDN访问

可以看到腾讯云CDN确实无需特殊配置即可支持WebSocket访问并透传源站。有一点在实际使用过程中需要注意的是节点默认支持10s的保活时间,10s内如果没有消息传递,将默认关闭连接。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python 实现 WebSocket 通信
WebSocket 协议主要用于解决Web前端与后台数据交互问题,在WebSocket技术没有被定义之前,前台与后端通信需要使用轮询的方式实现,WebSocket则是通过握手机制让客户端与服务端建立全双工通信,从而实现了更多复杂的业务需求。
王 瑞
2022/12/28
2.1K0
websocket
这时启动django项目会报错CommandError: You have not set ASGI_APPLICATION, which is needed to run the server.
GH
2020/03/19
3K0
一文读懂 WebSocket 通信过程与实现
来源:Python那些事 ID:PythonSomething 什么是 WebSocket ? WebSocket 是一种标准协议,用于在客户端和服务端之间进行双向数据传输。但它跟 HTTP 没什么关系,它是一种基于 TCP 的一种独立实现。 以前客户端想知道服务端的处理进度,要不停地使用 Ajax 进行轮询,让浏览器隔个几秒就向服务器发一次请求,这对服务器压力较高。另外一种轮询就是采用 long poll 的方式,这就跟打电话差不多,没收到消息就一直不挂电话,也就是说,客户端发起连接后,如果没消息,就一
小小科
2018/06/20
2.3K0
一文读懂 WebSocket 通信过程与实现
WebSocket 是一种标准协议,用于在客户端和服务端之间进行双向数据传输。但它跟 HTTP 没什么关系,它是一种基于 TCP 的一种独立实现。
前端教程
2018/07/27
7620
一文读懂 WebSocket 通信过程与实现
WebSocket相关
原文:http://www.cnblogs.com/jinjiangongzuoshi/p/5062092.html 前言 今天看了一些资料,记录一下心得。 websocket是html5引入的一个新特性,传统的web应用是通过http协议来提供支持,如果要实时同步传输数据,需要轮询,效率低下 websocket是类似socket通信,web端连接服务器后,握手成功,一直保持连接,可以理解为长连接,这时服务器就可以主动给客户端发送数据,实现数据的自动更新。 使用websocket需要注意浏览器和当前的
新人小试
2018/07/05
5780
go的websocket实现原理与用法详解
本文实例讲述了go的websocket实现原理与用法。分享给大家供大家参考,具体如下: websocket分为握手和数据传输阶段,即进行了HTTP握手 + 双工的TCP连接 RFC协议文档在:http
李海彬
2018/03/22
1K0
go的websocket实现原理与用法详解
WebSocket 学习笔记--IE,IOS,Android等设备的兼容性问题与代码实现
一、背景 公司最近准备将一套产品放到Andriod和IOS上面去,为了统一应用的开发方式,决定用各平台APP嵌套一个HTML5浏览器来实现,其中数据通信,准备使用WebSocket的方式。于是,我开始在各大浏览器上测试。 二、协议分析 2.1 WebSocket的请求包 首先把原来做Socket通信的程序拿出来,跟踪下浏览器在WebSocket应用请求服务端的时候发的数据包的内容: IE11: GET /chat HTTP/1.1 Origin: http://localhost Sec-WebSock
用户1177503
2018/02/27
3.2K1
WebSocket 学习笔记--IE,IOS,Android等设备的兼容性问题与代码实现
简单WiFi控制小车系统(树莓派+python+web控制界面)
   蛇皮走位演示视频: https://pan.baidu.com/s/1RHHr8bRHWzSEAkrpwu99aw
Fivecc
2022/11/21
1.7K0
简单WiFi控制小车系统(树莓派+python+web控制界面)
Nginx支持WebSocket反向代理-学习小结
WebSocket是目前比较成熟的技术了,WebSocket协议为创建客户端和服务器端需要实时双向通讯的webapp提供了一个选择。其为HTML5的一部分,WebSocket相较于原来开发这类app的方法来说,其能使开发更加地简单。大部分现在的浏览器都支持WebSocket,比如Firefox,IE,Chrome,Safari,Opera,并且越来越多的服务器框架现在也同样支持WebSocket。
洗尽了浮华
2018/08/22
3.1K0
Nginx支持WebSocket反向代理-学习小结
php实现websocket实时消息推送
软件通信有七层结构,下三层结构偏向与数据通信,上三层更偏向于数据处理,中间的传输层则是连接上三层与下三层之间的桥梁,每一层都做不同的工作,上层协议依赖与下层协议。基于这个通信结构的概念。
OwenZhang
2021/12/08
2.6K0
php实现websocket实时消息推送
【详解】Nginx配置WebSocket
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
大盘鸡拌面
2025/03/29
1.2K0
WebSocket协议入门介绍
WebSocket是基于TCP的应用层协议,用于在C/S架构的应用中实现双向通信,关于WebSocket协议的详细规范和定义参见rfc6455。 需要特别注意的是:虽然WebSocket协议在建立连接时会使用HTTP协议,但这并意味着WebSocket协议是基于HTTP协议实现的。
编程随笔
2019/06/27
2.1K0
WebSocket协议入门介绍
PHP的socket扩展
我们了解了常用的网络协议,今天我们来了解下socket服务。我们可以基于tcp和udp来实现我们的socket服务,
老雷PHP全栈开发
2020/07/02
1.6K0
PHP的socket扩展
PHP webSocket实现网页聊天室
http请求只能由客户端主动发起,服务器响应的模式, 服务器无法主动向客户端推数据,websocket的出现完美的解决了这一问题。 websocket和http处于同一层,都是基于TCP协议的,客户端和服务器使用websocket通讯的时候需要握手和传输数据两步, 握手借助http状态码101 switch protocol从http协议转换到websocket协议,之后便和http协议无关了。
用户3094376
2018/09/12
7.4K0
3分钟使用 WebSocket 搭建属于自己的聊天室(WebSocket 原理、应用解析)
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
Lorin 洛林
2023/11/22
3.8K1
3分钟使用 WebSocket 搭建属于自己的聊天室(WebSocket 原理、应用解析)
PHP是如何实现websocket实时消息推送的
什么是WebSocket WebSocket用于在Web浏览器和服务器之间进行任意的双向数据传输的一种技术。WebSocket协议基于TCP协议实现,包含初始的握手过程,以及后续的多次数据帧双向传输过程。 其目的是在WebSocket应用和WebSocket服务器进行频繁双向通信时,可以使服务器避免打开多个HTTP连接进行工作来节约资源,提高了工作效率和资源利用率。
友儿
2022/09/11
1.2K0
「IM系列」WebSocket教程:WS和WSS域名访问配置
WebSocket协议与HTTP协议不同,但WebSocket握手与HTTP兼容,使用HTTP升级工具将连接从HTTP升级到WebSocket。这允许WebSocket应用程序更容易地适应现有的基础设施。例如,WebSocket应用程序可以使用标准HTTP端口80和443,从而允许使用现有的防火墙规则。
Tinywan
2023/12/19
9.7K0
「IM系列」WebSocket教程:WS和WSS域名访问配置
WebSocket 基础与应用系列 —— 抓个 WebSocket 的包
在传统的 Web 中,要实现实时通信,通用的方式是采用 HTTP 协议不断发送请求,即轮询(Polling)。
程序员海军
2021/10/11
1.3K0
WebSocket 基础与应用系列 ——  抓个 WebSocket 的包
用Python实现一个简单的WebSoc
windows python 2.79, chrome37 firefox35通过
py3study
2020/01/06
5570
WebSocket协议 8 问
WebSocket是一种比较新的协议,它是伴随着html5规范而生的,虽然还比较年轻,但大多主流浏览器都已经支持。它使用方便、应用广泛,已经渗透到前后端开发的各种场景中。
xjjdog
2019/09/24
9730
WebSocket协议 8 问
相关推荐
Python 实现 WebSocket 通信
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档