简而言之,WebSocket服务器是在遵循协议调用WS(或WSS)的任何TCP端口服务器上侦听的应用程序。
通常,反向代理(例如HTTP服务器)用于检测Websocket握手,对其进行处理并将这些客户端发送到WebSocket服务器。WebSocket协议旨在与现有的Web基础结构良好配合。作为此设计原则的一部分,WebSocket连接从HTTP连接开始,并与WebSocket之前的版本完全向后兼容。从HTTP到WebSocket的协议转换称为握手。
客户端发送升级头:
--- request header --- GET / HTTP/1.1 Upgrade: websocket Connection: Upgrade Host: localhost:4040 Origin: http://localhost:4040 Sec-WebSocket-Key: q0+vBfXgMvGGywjDaHZWiw== Sec-WebSocket-Version: 13
如果服务器理解WebSocket协议,则表示它同意通过升级标头进行协议切换。
----------------------- --- response header --- HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: /YqMq5iNGOMjtELPGCZsnozMSlw= Date: Sun, 15 Sep 2019 23:34:04 GMT Server: Python/3.7 websockets/8.0.2 -----------------------
此时,HTTP连接断开,并由基础TCP / IP连接上的WebSocket连接代替。WebSocket与HTTP类似,默认情况下使用HTTP(80)和HTTPS(443)。
实时应用程序–需要在没有客户端请求数据的情况下更新UI的情况。在这里,WebSockets比使用传统的AJAX轮询更快,后者使用HTTP
游戏应用
聊天应用
不需要实时更新。WebSockets,因为在组件之一关闭连接之前,该连接一直处于活动状态。相反,RESTful服务足以从服务器获取数据。
Python提供了许多库来实现WebSocket服务器。以下是市场上可用的少数几个。这些库可以通过Pypi轻松安装在虚拟环境或Anaconda环境中。
WebSockets:https://pypi.org/project/websockets/
龙卷风:https://pypi.org/project/tornado/
1)使用WebSockets库(ws_server.py)
import asyncio import websockets import time import json async def say_hello(websocket, path): while True: await websocket.send("hello world") time.sleep(10) # 服务器在localhost和端口4040中启动 start_server = websockets.serve(say_hello,'localhost',4040) asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever()
2)使用龙卷风库(tornado_ws_server.py)
''' This module hosts a websocket server using tornado libraries ''' import tornado.web import tornado.httpserver import tornado.ioloop import tornado.websocket as ws from tornado.options import define, options import time define('port', default=4041, help='port to listen on') class web_socket_handler(ws.WebSocketHandler): ''' This class handles the websocket channel ''' @classmethod def route_urls(cls): return [(r'/',cls, {}),] def simple_init(self): self.last = time.time() self.stop = False def open(self): ''' client opens a connection ''' self.simple_init() print("New client connected") self.write_message("You are connected") def on_message(self, message): ''' Message received on the handler ''' print("received message {}".format(message)) self.write_message("You said {}".format(message)) self.last = time.time() def on_close(self): ''' Channel is closed ''' print("connection is closed") def check_origin(self, origin): return True def initiate_server(): #创建一个龙卷风应用程序并提供网址 app = tornado.web.Application(web_socket_handler.route_urls()) #设置服务器 server = tornado.httpserver.HTTPServer(app) server.listen(options.port) #开始io /事件循环 tornado.ioloop.IOLoop.instance().start() if __name__ == '__main__': initiate_server()
创建虚拟环境
-bash-4.2 $python3 -m venv venv
源(或激活)虚拟环境
-bash-4.2 $源venv / bin / activate
使用pip安装所需的库
(venv) -bash-4.2$ pip3 install websockets Collecting websockets Downloading https://files.pythonhosted.org/packages/f0/4b/ad228451b1c071c5c52616b7d4298ebcfcac5ae8515ede959db19e4cd56d/websockets-8.0.2-cp36-cp36m-manylinux1_x86_64.whl (72kB) 100% |████████████████████████████████| 81kB 2.1MB/s Installing collected packages: websockets Successfully installed websockets-8.0.2 (venv) -bash-4.2$ (venv) -bash-4.2$ pip3 install tornado Collecting tornado Using cached https://files.pythonhosted.org/packages/30/78/2d2823598496127b21423baffaa186b668f73cd91887fcef78b6eade136b/tornado-6.0.3.tar.gz Installing collected packages: tornado Running setup.py install for tornado ... done Successfully installed tornado-6.0.3 (venv) -bash-4.2$ Execute the sample websocket server Python3 tornado_ws_server.py Or Python3 ws_server.py
参考文献:
https://github.com/postrank-labs/goliath/issues/199
https://github.com/tinyproxy/tinyproxy/issues/101