全部主题 | Blog | 时讯 | @fullstackpython | Facebook | 源码
WebSockets
WebSocket 是一种 标准协议,用于在客户端和服务端之间进行双向数据传输。WebSockets 协议没有运行在 HTTP 之上,它是基于 TCP 的一种独立实现。
为什么要用 WebSockets?
一个 WebSocket 连接允许在客户端和服务端之间进行全双工通讯,从而每一端都可以通过建立的连接向另一端推送数据。 WebSocket,以及与其相关的 服务端发送事件 (SSE) 及 WebRTC 数据通路 等技术之所以重要的原因是:HTTP不能打开并一直保持连接,不能在服务端和 Web 浏览器之间进行频繁的数据推送。在这之前,大多数的 Web 应用会通过频繁的异步 JavaScript 和 XML (AJAX) 请求来实现长轮循,如下图所示。
服务端推送相比长轮循效率更高且更具扩展性,因为 Web 浏览器不再需要通过一系列的 AJAX 请求来持续地获取更新。
虽然上图中所示的是服务端将数据推送给客户端,但是 WebSocket 是一个全双工的连接,因此客户端也能将数据推送给服务端,如下图所示。
用 WebSockets 来获取服务端/客户端推送的更新,这种方式适合特定类型的 Web 应用,例如聊天室,这也是它之所以经常被用作 WebSocket 库的示例应用的原因。
实现 WebSocket
Web 浏览器和服务端都必须要实现 WebSocket 协议,以便建立和维护连接。因为 WebSocket 的连接是持续连通的,不像经典的 HTTP 连接,因此服务器需要做更多工作。
基于多线程或多进程的服务器不能很好地提供 WebSockets 服务,因为它们的设计是:打开一个连接,尽快处理完请求,然后关闭连接。因此,采用 Tornado 或 打包了 gevent 的 Green Unicorn 等异步服务器,对于实现一个实用的服务端 WebSockets 都是必要的。
而在客户端,使用 WebSocket 并不要求有某个 JavaScript 库。实现了 WebSocket 的 Web 浏览器都会通过 WebSockets 对象 导出所有必要的客户端功能。
但是,JavaScript 封装库实现了优雅地降级(不支持 WebSocket 的情况下通常会采用长轮循机制),并隐藏了不同浏览器间的羞异,使用这些封闭库,会使开发者工作起来更加轻松。 有关 JavaScript 客户端库及 Python 实现的示例在下面列出。
JavaScript 客户端库
Socket.io 的客户端 JavaScript 库能与实现了 WebSocket 的服务端进行连接。
web-socket-js 是一个基于 Flash 的客户端 WebSocket 实现。
Python 实现
Autobahn 使用 Twisted 或 asyncio 来实现 WebSocket 协议。
Crossbar.io 构建于 Autobahn 之上,并且包含一个独立的服务器, 如果 Web 应用开发者需要的话,可以用它来对 WebSocket 连接进行单独处理。
Nginx WebSocket 代理
Nginx 从 第 1.3 版 开始就正式支持 WebSocket 代理了,通过配置 Upgrade 和 Connection 头可以确保请求通过 Nginx 并到达你的 WSGI 服务器。第一次设置可能会有一点难度。
下面是我的 WebSockets 代理的 Nginx 配置。
- # this is where my WSGI server sits answering only on localhost
- # usually this is Gunicorn monkey patched with gevent
- upstream app_server_wsgiapp {
- server localhost:5000 fail_timeout=0;
- }
- server {
- # typical web server configuration goes here
- # this section is specific to the WebSockets proxying
- location /socket.io {
- proxy_pass http://app_server_wsgiapp/socket.io;
- proxy_redirect off;
- 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 "upgrade";
- proxy_read_timeout 600;
- }
- }
值得注意的是,如何上面的示例配置不能工作,你应该查看 官方的 HTTP 代理模块文档。
下面的这些资源对于正确的配置也很有帮助。
Nginx 上有与 WebSocket 代理相关的官方页面。
Nginx 中的 WebSockets 历数了 Nginx WebSockets 的配置指令。
用 Nginx 代理 WebSockets 展示了如何通过 Socket.io 进行代理。
使用 WebSockets 的开源 Python 示例
python-websockets-example 包含了创建一个简单 Web 应用的代码,它使用 Flash、Flask-SocketIO 和 gevent 来提供 WebSockets。
- Flask-SocketIO 项目中有一个 聊天室 Web 应用,演示了如何发送服务端生成的事件,以及如何通过表单的文本输入框来获取用户输入。
通用 WebSocket 资源
官方的 W3C WebSockets API 候选草案 和 WebSockets 工作草案 都是不错的参考材料,但是对于刚接触 WebSockets 概念的开发者来说会有点难度。我建议先看下面列出的一些对初学者来说较容易的资料,然后再读那份工作草案。
由 Armin Ronacher 写的 WebSockets 101 提供了一份有关 HTTP 代理对 WebSockets 低水平支持的详细评估报告。同时对 WebSockets 协议的复杂性及其实现也进行了探讨。
"我能使用吗?" 网站上有一份 非常有用的 WebSockets 参照表,指出了哪些浏览器及其版本支持 WebSockets。
Mozilla 的 WebSockets 开发者资源 是一个查找 WebSockets 开发相关文档与工具的好地方。
从零开始学 WebSockets 先对该协议进行了概述,然后对 WebSockets 的低层知识进行了讲解,这些知识对于只使用 Socket.IO 等库的开发人员来说通常是个黑盒子。
websocketd 是一个 WebSockets 服务程序,意在成为 "WebSockets 的 CGI"。值得一看。
Python 相关的 WebSockets 资源
我在 2015 年 1月份的 San Francisco Python 上的演讲中提到了 "使用 WebSockets & gevent 实现异步 Python Web Apps",它是一个实时编写的 Flask Web 示例应用,如我创建的应用所示,它可以让用户通过 Websockets 实现互动。
Python 的实时操作 提供了 Python 相关的背景知识,叙述了在 Python 中过去是如何实现服务端更新推送的,以及随着 Python 工具的发展,现在是如何执行服务端更新的。
websockets 是一个基于 Python 3.3+ 的 WebSockets 实现,它使用了 asyncio 模块 ( 如果你使用的是 Python 3.3 的话,是 Tulip )。
交互式的演示文稿 这篇教程在服务端通过 gevent 实现 WebSockets,并使用 socketio.js 将投票数从服务端推送x给客户端。
为 Django 应用增加实时功能 讲解了如何使用 Django 和 Crossbar.io 在应用中实现发布/订阅功能。
异步 Bottle 讲解了在 Bottle Web 框架中如何使用 greenlets 来支持 WebSockets。
如果你部署到 Heroku 的话, 这里的这篇 WebSockets 相关指南 能帮助你部署你的 Python 应用。
Reddit 上的相关页面 有一些很有意思的评论,填补了我上面缺失的一点内容。
用 Python 和 Websockets 创建聊天室应用 展示了处理服务端 Websockets 连接的 Twisted 服务器代码及客户端的 JavaScript 代码。
使用 Websockets 实现 Flask 应用的客户端同步 这份简短的教程,讲解了如何使用 Flask、Flask-SocketIO 扩展和 Socket.IO 实现在各浏览器客户端间更新数据。
WebSockets 能和 HTTP/2 共存吗? 先对这两个协议进行了对比,然后阐述了它们之间的差异可能会导致 WebSockets 会被使用更长时间。
针对你的 Web 应用,接下来要做什么?
想找到一个完整的,一步一步的部署方案吗?请看《The Full Stack Python Guide to Deployments》.
邮件获取更新
目录
1. 简介学习编程为什么用 Python?Python 2 还是 3?企业 PythonPython CommunityBest Python Podcasts最佳 Python 资源最佳 Python 视频2. 开发环境VimEmacs3. 核心语言生成器推导式4. Web 开发Web 框架DjangoFlaskBottlePyramidMorepath其它 Web 框架Web 设计级联样式表 (CSS)JavaScriptWebSockets模板引擎Web 应用安全静态网站生成器Jinja25. 数据关系型数据库NoSQL 数据存储对象关系映射器PostgreSQLMySQLSQLite6. Web APIsAPI 集成API 的创建Twilio7. 部署服务器平台即服务(PaaS)操作系统Web 服务器WSGI 服务器源码控制应用程序依赖静态内容任务队列配置管理持续集成日志监控Web 分析Docker缓存微服务DevOpsNginxApache HTTP 服务器CaddyGreen Unicorn (Gunicorn)UbuntuPelicanLektorMkDocs8. 测试单元测试集成测试代码度量调试9. MetaBotsChange LogFuture DirectionsAbout the AuthorSQLAlchemyPeewee …或者显示全部目录内容.
WebSockets
重要的更新内容会通过 Twitter 账号@fullstackpython发布。
需要更加详细的教程吗?请看 《The Full Stack Python Guide to Deployments》。
Chapters
1. 简介2. 开发环境3. 核心语言4. Web 开发 » WebSockets 5. 数据6. Web APIs7. 部署8. 测试9. Meta …or view the full table of contents.
This site is based on Matt Makai's project Full Stack Python, thanks for his excellent work!
此网站由 @haiiiiiyun 和 开源爱好者们 共同维护。 若发现错误或想贡献,请访问: Github fullstackpython.cn 项目