在tornado项目中使用WebSocket实现聊天室功能

一、创建chat.py,在其中添加如下代码

import uuid
import tornado.web
import tornado.escape
from tornado.websocket import WebSocketHandler
from .main import BaseHandler


class ChatRoomHandler(BaseHandler):
    @tornado.web.authenticated
    def get(self):
        return self.render('room.html')


class ChatWSHandler(WebSocketHandler):
    """处理和响应websocket连接"""
    waiters = set()
    def open(self):
        # 新的websocket连接打开,自动调用
        print('new wb connection')
        ChatWSHandler.waiters.add(self)

    def on_message(self, message):
        # websocket服务端收到消息自动调用
        print('got message: {}'.format(message))
        # 服务端给客户端发消息
        # self.write_message('got: [{}]'.format(message))
        parsed = tornado.escape.json_decode(message)
        uid = uuid.uuid4().hex
        chat = {
            'id': uid,
            'html': '<h2 id="m{}">{}</h2>'.format(uid, parsed['body'])
        }
        for w in ChatWSHandler.waiters:
            w.write_message(chat)

    def on_close(self):
        # 客户端关闭连接时,自动调用
        print('close ws connection')
        ChatWSHandler.waiters.remove(self)

二、创建room.html,在其中添加如下代码

<!DOCTYPE html>
{% extends base.html %}
{% block title %}
    chat_room page
{% end %}
{% block link %}
<style>
    #inbox{
        color: orange;
    }
</style>
{% end %}
{% block content %}
    <div id="inbox"></div>
    <div id="input">
        <form action="#" method="post" id="messageform">
            <table>
                <tr>
                    <td>
                        <input name="body" id="message" type="text" style="width: 500px">
                    </td>
                    <td style="padding-left: 5px;">
                        <input type="submit" value="发送">
                    </td>
                </tr>
            </table>
        </form>
    </div>
{% end %}
{% block script %}
    <script src="{{ static_url('js/chat.js') }}"></script>
{% end %}

三、创建chat.js,在其中添加如下代码

$(document).ready(function() {
    if (!window.console) window.console = {};
    if (!window.console.log) window.console.log = function() {};

    $("#messageform").on("submit", function() {  // 点击提交时执行
        newMessage($(this));
        return false;
    });
    $("#messageform").on("keypress", function(e) {  // 回车提交时执行
        if (e.keyCode == 13) {
            newMessage($(this));
            return false;
        }
    });
    $("#message").select();
    updater.start();   // 开始 WebSocket
});

function newMessage(form) {     // 发送新消息给服务器
    var message = form.formToDict();
    updater.socket.send(JSON.stringify(message));
    $("input[name='body']").val("").select();
}

jQuery.fn.formToDict = function() {
    var fields = this.serializeArray();
    var json = {};
    for (var i = 0; i < fields.length; i++) {
        json[fields[i].name] = fields[i].value;
    }
    if (json.next) delete json.next;
    return json;
};

var updater = {
    socket: null,

    start: function() {
        var url = "ws://" + location.host + "/ws";
        updater.socket = new WebSocket(url);  // 初始化 WebSocket
        updater.socket.onmessage = function(event) {  // 获取到服务器的信息时响应
            updater.showMessage(JSON.parse(event.data));
        }
    },

    showMessage: function(message) {
        var existing = $("#m" + message.id);
        if (existing.length > 0) return;
        var node = $(message.html);
        node.hide();
        $("#inbox").append(node);  // 添加消息 DIV 到页面
        node.slideDown();
    }
};

四、效果展示页

在这里插入图片描述
点击获取github源码

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值