如何使用Tornado实现WebSocket服务器?

什么是Tornado?

Tornado是一个python Web框架和异步网络库。它具有可伸缩性和非阻塞性。它专门处理事件驱动的网络。由于龙卷风支持并发连接,因此服务器自然可以利用此行为并在单个节点内处理大量Web套接字连接。

什么是Websocket?

WebSocket是一种协议,可通过单个TCP连接提供全双工通信通道。开放套接字的行为使Web连接变为无状态,并促进了与服务器之间的实时数据传输。

WebSockets设计用于Web浏览器和服务器。连接一次打开,并且消息可以在关闭连接之前往返传输多次。

安装Tornado

在使用pip的虚拟环境中安装Tornado非常简单。

  • 创建一个虚拟环境
    python3 -m venv / path / to / virtual / environment
    >> python3 -m venv venv

  • 来源虚拟环境
    >>来源venv / bin / activate

  • 使用pip >>(venv)安装websocket-client
    pip3 install tornado

  Using cached https://files.pythonhosted.org/packages/30/78/2d2823598496127b21423baffaa186b668f73cd91887fcef78b6eade136b/tornado-6.0.3.tar.gz
Requirement already satisfied: six in ./venv/lib/python3.7/site-packages (from websocket_client==0.56.0->-r requirements.txt (line 1)) (1.12.0)
Installing collected packages: tornado
  Running setup.py install for tornado ... done
Successfully installed tornado-6.0.3

使用Tornado库启动Web套接字服务器的Python示例

'''
    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")
        self.loop.stop()
    
    def check_origin(self, origin):
        return True

def initiate_server():
    #create a tornado application and provide the urls
    app = tornado.web.Application(web_socket_handler.route_urls())
    
    #setup the server
    server = tornado.httpserver.HTTPServer(app)
    server.listen(options.port)
    
    #start io/event loop
    tornado.ioloop.IOLoop.instance().start()


if __name__ == '__main__':
    initiate_server()

上面的代码将在localhost端口4041上启动服务器。

使用websocket客户端代码连接到服务器(以下示例),

from websocket import create_connection

def short_lived_connection():

    ws = create_connection("ws://localhost:4040/")
    print("Sending 'Hello Server'...")
    ws.send("Hello, Server")
    print("Sent")
    print("Receiving...")
    result =  ws.recv()
    print("Received '%s'" % result)
    ws.close()

if __name__ == '__main__':
    short_lived_connection()

输出(客户端):

>>Sending 'Hello, Server'...
>>Sent
>>Receiving...
>>Received 'You are connected'

输出(服务器端):

>>New client connected
>>received message Hello, Server
>>connection is closed