Tornado---websocket实时推送技术3

聊天室功能

服务器端:

import logging
import tornado.escape
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.websocket
import os.path
import uuid

from tornado.options import define, options
define("port", default=8888, help="run on the given port", type=int)

class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/", MainHandler),
            (r"/websocket", ChatSocketHandler),
        ]
        settings = dict(
            cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
            template_path=os.path.join(os.path.dirname(__file__), "templates"),
            static_path=os.path.join(os.path.dirname(__file__), "static"),
            xsrf_cookies=True,
        )
        tornado.web.Application.__init__(self, handlers, **settings)


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("index.html", messages=ChatSocketHandler.cache)


class ChatSocketHandler(tornado.websocket.WebSocketHandler): 
    waiters = set()
    cache = []
    cache_size = 200

    def allow_draft76(self):
        # for iOS 5.0 Safari
        return True

    def open(self):
        print "new client opened"
        ChatSocketHandler.waiters.add(self)

    def on_close(self):
        ChatSocketHandler.waiters.remove(self)

    @classmethod
    def update_cache(cls, chat):
        cls.cache.append(chat)
        if len(cls.cache) > cls.cache_size:
            cls.cache = cls.cache[-cls.cache_size:]

    @classmethod
    def send_updates(cls, chat):
        logging.info("sending message to %d waiters", len(cls.waiters))
        for waiter in cls.waiters:
            try:
                waiter.write_message(chat)
            except:
                logging.error("Error sending message", exc_info=True)

    def on_message(self, message):
        logging.info("got message %r", message)

        ChatSocketHandler.send_updates(message)


if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = Application()
    # app.listen(8080)
    app.listen(options.port)
    print("visit at", "http://127.0.0.1:%s" % options.port)
    tornado.ioloop.IOLoop.instance().start()

客户端:

<html><head><title>Web Socket Client</title></head>
<body>
<script type="text/javascript">
    var socket;
    if (!window.WebSocket) {
        window.WebSocket = window.MozWebSocket;
    }

    // Javascript Websocket Client
    if (window.WebSocket) {
        socket = new WebSocket("ws://127.0.0.1:8888/websocket");
        socket.onmessage = function(event) {
            var ta = document.getElementById('responseText');
            ta.value = ta.value + '\n' + event.data;
        };

        socket.onopen = function(event) {
            var ta = document.getElementById('responseText');
            ta.value = "Web Socket opened!";
        };

        socket.onclose = function(event) {
            var ta = document.getElementById('responseText');
            ta.value = ta.value + "Web Socket closed";
        };

    } else {
        alert("Your browser does not support Web Socket.");
    }

    // Send Websocket data
    function send(message) {
        if (!window.WebSocket) { return; }
        if (socket.readyState == WebSocket.OPEN) {
            socket.send(message);
        } else {
            alert("The socket is not open.");
        }
    }
</script>

<h3>Send :</h3>
<form onsubmit="return false;">
<input type="text" name="message" value="Hello World!"/><input type="button" value="Send Web Socket Data" onclick="send(this.form.message.value)" />
<h3>Receive :</h3>
<textarea id="responseText" style="width:500px;height:300px;"></textarea>
</form>
</body>
</html>

 

qq群聊功能

服务器端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import logging
import tornado.escape
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.websocket import WebSocketHandler
import os.path

from tornado.options import define, options
define("port", default=8888, help="run on the given port", type=int)

class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/", MainHandler),
            (r"/chat", ChatHandler),
        ]
        settings = dict(
            cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
            template_path=os.path.join(os.path.dirname(__file__), "templates"),
            static_path=os.path.join(os.path.dirname(__file__), "static"),
            xsrf_cookies=True,
        )
        tornado.web.Application.__init__(self, handlers, **settings)


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("home.html")


class ChatHandler(WebSocketHandler):
    #存储每一个人的信息
    users = [] 

    # 判断源origin,对于符合条件的请求源允许链接
    def check_origin(self, origin):
        return True

    def allow_draft76(self):
        # for iOS 5.0 Safari
        return True

    # 连接建立后被调用,客户端建立链接后调用open。
    def open(self):
        print "new client opened===>"
        # 链接上后再进行存储用户信息,self 为每个连接服务器的客户端的对象
        self.users.append(self)
        for user in self.users:
            print(self.request.remote_ip)
            # 主动向客户端发送message消息,message可以是字符串或者字典。
            user.write_message('u[{}]登陆了'.format(self.request.remote_ip))


    # 客户端发送消息过来时服务器调用on_message
    def on_message(self, message):
        # 如果前端发的数据是字典,需要转一下
        # parsed = tornado.escape.json_decode(message)
        for user in self.users:
            # write_message的消息会被前端ws.onmessage方法接收
            user.write_message(u'{}说:{}'.format(self.request.remote_ip,message))


    # 客户端断开链接调用on_close
    def on_close(self):
        print "new client closed===>"
        self.users.remove(self)
        for user in self.users:
            print(user)
            user.write_message('u[{}]退出登陆了'.format(self.request.remote_ip))


if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = Application()
    # app.listen(8080)
    app.listen(options.port)
    print("visit at", "http://127.0.0.1:%s" % options.port)
    tornado.ioloop.IOLoop.instance().start()

客户端:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>聊天界面</title>
    <script type="text/javascript" charset="UTF-8" src="{{static_url('js/jquery-3.3.1.min.js')}}"></script>
</head>
<body>
    <div id="contents" style="width: 500px;height: 500px;overflow: auto"></div>
    <div>
        <input type="text" id="message" />
        <button onclick="sendMessage()">发送</button>
    </div>

    <script>
        //建立WebSocket链接,连接之后,服务器端调用open方法,客户端调用onopen方法。初始化一个 WebSocket对象。
        var ws = new WebSocket('ws://127.0.0.1:8888/chat');

        // 建立 websocket连接 成功触发事件。
        ws.onopen = function (event) {
            var userobj = {"msgid":1,"userid":"123","devid":666};
            // 使用 send() 方法发送数据
            ws.send(JSON.stringify(userobj));
        };

        // 断开 websocket连接 成功触发事件。
        ws.onclose = function (event) {
            /*不一定能发送过去*/
            var userobj = {"msgid":2,"userid":456,"devid":888};
            ws.send(JSON.stringify(userobj));
        };

        //接收服务器消息。然后再发信息给服务器。
        ws.onmessage = function (e) {
            $('#contents').append("<p>"+e.data+"</p>")
            var userobj = {"msgid":2,"userid":456,"devid":888};
            ws.send(JSON.stringify(userobj));
        };

        //向服务器发送消息。主动发信息给服务器。
        function sendMessage() {
            // console.log('*************')
            var message = $('#message').val();
            ws.send(message);
            $('#message').val("")
        }
    </script>
</body>
</html>

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值