About

风之力 - Tornado 搭建基于 WebSocket 的聊天服务

    这年头 Python web 框架是有点泛滥了. 下面要介绍的是 facebook 的开源框架 tornado. 这东西比较简单, 而且自带 WebSocket 支持, 可以用它做个简单的聊天室.
    读者最好已具备 Javascript 与 WebSocket 的基础知识.

安装

    使用 easy_install 能很方便地爬到 tornado. 或者, 下载源代码, 解包后在源码目录执行
$ python setup.py build
# python setup.py install
即可.

开张

    首先还是来个 hello world.
import tornado.web
import tornado.ioloop

class Index(tornado.web.RequestHandler):
    def get(self):
        self.write('
Hello, world!')

if __name__ == '__main__':
    app = tornado.web.Application([
        ('/', Index),
    ])
    app.listen(8000)
    tornado.ioloop.IOLoop.instance().start()
    保存为 main.py, 然后执行
$ python main.py
    并访问 http://localhost:8000/ 即可看到页面中的 "Hello, world!".

    在分支中定义的 app 在构造时接受的一个列表参数
[
    ('/', Index),
]
用来配置 URL 映射, 比如这里访问根路径则映射至 Index 实例去处理, 在 Index 实例中, 定义的 get 方法将会处理请求.

处理 WebSocket 连接

添加请求处理类

    接下来就进入 WebSocket 环节. 先修改返回的页面, 让这个页面在加载后连接服务器.
class Index(tornado.web.RequestHandler):
    def get(self):
        self.write('''






        ''')
    修改这个类后, 然后在控制台中止服务器 (猛击 Ctrl-C), 并重新启动之.
    现在, 访问 http://localhost:8000/ 会遇到 404 错误, 因为 WebSocket 请求的 URL "ws://localhost:8000/soc" 还没有映射任何处理器, 因此这里需要再添加一个, 用于处理 WebSocket 请求的类.
import tornado.websocket

class SocketHandler(tornado.websocket.WebSocketHandler):
    def open(self):
        self.write_message('Welcome to WebSocket')
    并为这个类加上 URL 映射
if __name__ == '__main__':
    app = tornado.web.Application([
        ('/', Index),
        ('/soc', SocketHandler),
    ])
    app.listen(8000)
    tornado.ioloop.IOLoop.instance().start()
    然后重启服务器, 并访问 http://localhost:8000/ 就可以在页面上看到服务器传来的信息了.

使用模板

    在进一步完善聊天功能之前, 先整理一下代码. 让大坨的 HTML 出现在 Python 源码文件中显然是件不合适的事情. 使用 render 函数可以处理模板 HTML 文件并传递给客户端.
class Index(tornado.web.RequestHandler):
    def get(self):
        self.render('templates/index.html')
    然后把先前的 HTML 内容放入 templates 目录下的 index.html 文件中. 再重启服务器, 这样就将 HTML 内容分离出去了.

管理连接者

    接下来要做的一件事情是记录客户端的连接. 在 SocketHandler 类里面放置一个集合, 用来记录开启着的连接.
class SocketHandler(tornado.websocket.WebSocketHandler):
    clients = set()

    def open(self):
        self.write_message('Welcome to WebSocket')
        SocketHandler.clients.add(self)

    def on_close(self):
        SocketHandler.clients.remove(self)
    然后再改改, 安排每个连接者给其它连接者打个招呼.
class SocketHandler(tornado.websocket.WebSocketHandler):
    clients = set()

    @staticmethod
    def send_to_all(message):
        for c in SocketHandler.clients:
            c.write_message(message)

    def open(self):
        self.write_message('Welcome to WebSocket')
        SocketHandler.send_to_all(str(id(self)) + ' has joined')
        SocketHandler.clients.add(self)

    def on_close(self):
        SocketHandler.clients.remove(self)
        SocketHandler.send_to_all(str(id(self)) + ' has left')
    再把首页给改改





<table id='message'>

Tags: Python Tornado Tutorial Web Server

Loading comments


. Back to Tobary book
Tobary book - Copyright (C) ZhePlus @ Bit Focus
About