mirror of
https://github.com/xfgryujk/blivechat.git
synced 2024-12-25 12:21:00 +08:00
添加文字消息
This commit is contained in:
parent
4cc549f3b0
commit
e72af2c4f7
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "blivedm"]
|
||||
path = blivedm
|
||||
url = https://github.com/xfgryujk/blivedm.git
|
1
blivedm
Submodule
1
blivedm
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit f755468908586d39a3325e9f1b0eced42a37ecc2
|
92
chat.py
Normal file
92
chat.py
Normal file
@ -0,0 +1,92 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import enum
|
||||
import json
|
||||
from typing import *
|
||||
|
||||
import tornado.websocket
|
||||
|
||||
import blivedm.blivedm as blivedm
|
||||
|
||||
|
||||
class Command(enum.IntEnum):
|
||||
JOIN_ROOM = 0
|
||||
ADD_TEXT = 1
|
||||
ADD_GIFT = 2
|
||||
ADD_VIP = 3
|
||||
|
||||
|
||||
class Room(blivedm.BLiveClient):
|
||||
def __init__(self, room_id):
|
||||
super().__init__(room_id)
|
||||
self.future = None
|
||||
self.clients: List['ChatHandler'] = []
|
||||
|
||||
def start(self):
|
||||
self.future = self.run()
|
||||
|
||||
def stop(self):
|
||||
if self.future is not None:
|
||||
self.future.cancel()
|
||||
|
||||
def send_message(self, cmd, data):
|
||||
body = json.dumps({'cmd': cmd, 'data': data})
|
||||
for client in self.clients:
|
||||
client.write_message(body)
|
||||
|
||||
async def _on_get_danmaku(self, content, user_name):
|
||||
# TODO
|
||||
data = {
|
||||
'content': content,
|
||||
'authorName': user_name
|
||||
}
|
||||
self.send_message(Command.ADD_TEXT, data)
|
||||
|
||||
|
||||
class RoomManager:
|
||||
def __init__(self):
|
||||
self._rooms: Dict[int, Room] = {}
|
||||
|
||||
def add_client(self, room_id, client):
|
||||
if room_id in self._rooms:
|
||||
room = self._rooms[room_id]
|
||||
else:
|
||||
room = Room(room_id)
|
||||
self._rooms[room_id] = room
|
||||
room.start()
|
||||
room.clients.append(client)
|
||||
|
||||
def del_client(self, room_id, client: 'ChatHandler'):
|
||||
if room_id not in self._rooms:
|
||||
return
|
||||
room = self._rooms[room_id]
|
||||
room.clients.remove(client)
|
||||
if not room.clients:
|
||||
room.stop()
|
||||
del self._rooms[room_id]
|
||||
|
||||
|
||||
room_manager = RoomManager()
|
||||
|
||||
|
||||
# noinspection PyAbstractClass
|
||||
class ChatHandler(tornado.websocket.WebSocketHandler):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.room_id = None
|
||||
|
||||
def on_message(self, message):
|
||||
if self.room_id is not None:
|
||||
return
|
||||
body = json.loads(message)
|
||||
if body['cmd'] == Command.JOIN_ROOM:
|
||||
room_id = body['data']['roomId']
|
||||
room_manager.add_client(room_id, self)
|
||||
|
||||
def on_close(self):
|
||||
if self.room_id is not None:
|
||||
room_manager.del_client(self.room_id, self)
|
||||
|
||||
# 测试用
|
||||
def check_origin(self, origin):
|
||||
return True
|
@ -1,9 +1,496 @@
|
||||
<template>
|
||||
<p>Room: {{$route.params.roomId}}</p>
|
||||
<yt-live-chat-renderer>
|
||||
<!-- <yt-live-chat-ticker-renderer>
|
||||
<yt-live-chat-ticker-paid-message-item-renderer style="background-color: rgba(0,184,212,1);">
|
||||
<div id="content">
|
||||
<span id="fake-avatar"></span>
|
||||
<span>$5.00</span>
|
||||
</div>
|
||||
</yt-live-chat-ticker-paid-message-item-renderer>
|
||||
<yt-live-chat-ticker-paid-message-item-renderer style="background-color: rgba(208,0,0,1);">
|
||||
<div id="content">
|
||||
<span id="fake-avatar"></span>
|
||||
<span>$500.00</span>
|
||||
</div>
|
||||
</yt-live-chat-ticker-paid-message-item-renderer>
|
||||
</yt-live-chat-ticker-renderer> -->
|
||||
<yt-live-chat-item-list-renderer>
|
||||
<text-message v-for="message in messages" :key="message.id"
|
||||
:avatarUrl="message.avatarUrl" :time="message.time" :authorName="message.authorName" :content="message.content"
|
||||
></text-message>
|
||||
</yt-live-chat-item-list-renderer>
|
||||
</yt-live-chat-renderer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TextMessage from './TextMessage.vue'
|
||||
|
||||
export default {
|
||||
name: 'Room'
|
||||
name: 'Room',
|
||||
components: {
|
||||
TextMessage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
websocket: null,
|
||||
messages: [],
|
||||
nextId: 0
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// this.websocket = new WebSocket(`ws://${window.location.host}/chat`)
|
||||
// 测试用
|
||||
this.websocket = new WebSocket('ws://localhost/chat')
|
||||
this.websocket.onopen = () => this.websocket.send(JSON.stringify({
|
||||
cmd: 0,
|
||||
data: {
|
||||
roomId: parseInt(this.$route.params.roomId)
|
||||
}
|
||||
}))
|
||||
this.websocket.onmessage = (event) => {
|
||||
let body = JSON.parse(event.data)
|
||||
switch(body.cmd) {
|
||||
case 1: // ADD_TEXT
|
||||
this.messages.push({
|
||||
id: this.nextId++,
|
||||
avatarUrl: '',
|
||||
time: '12:00',
|
||||
authorName: body.data.authorName,
|
||||
content: body.data.content
|
||||
})
|
||||
window.scrollTo(0, document.body.scrollHeight)
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.websocket.close()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
yt-live-chat-text-message-renderer {
|
||||
position: relative;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-ms-flex-direction: row;
|
||||
-webkit-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-ms-flex-align: start;
|
||||
-webkit-align-items: flex-start;
|
||||
align-items: flex-start;
|
||||
padding: 4px 24px;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer #content {
|
||||
-ms-align-self: center;
|
||||
-webkit-align-self: center;
|
||||
align-self: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer #timestamp {
|
||||
display: none;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer #author-name {
|
||||
margin-right: 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer #author-photo {
|
||||
display: inline-block;
|
||||
background-color: transparent;
|
||||
-ms-flex: none;
|
||||
-webkit-flex: none;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer #author-badges {
|
||||
vertical-align: text-bottom;
|
||||
display: -ms-inline-flexbox;
|
||||
display: -webkit-inline-flex;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer #message {
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
yt-live-chat-author-badge-renderer {
|
||||
display: block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: currentColor;
|
||||
margin-right: 4px;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
yt-live-chat-legacy-paid-message-renderer {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
margin: 8px 24px;
|
||||
padding: 8px 16px;
|
||||
background-color: #0f9d58;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
min-height: 40px;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-ms-flex-direction: row;
|
||||
-webkit-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-ms-flex-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
yt-live-chat-legacy-paid-message-renderer #author-photo {
|
||||
background-color: transparent;
|
||||
margin-right: 16px;
|
||||
overflow: hidden;
|
||||
-ms-flex: none;
|
||||
-webkit-flex: none;
|
||||
flex: none;
|
||||
-ms-align-self: flex-start;
|
||||
-webkit-align-self: flex-start;
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
yt-live-chat-legacy-paid-message-renderer #content {
|
||||
-ms-flex: 1 1 0.000000001px;
|
||||
-webkit-flex: 1;
|
||||
flex: 1;
|
||||
-webkit-flex-basis: 0.000000001px;
|
||||
flex-basis: 0.000000001px;
|
||||
}
|
||||
|
||||
yt-live-chat-legacy-paid-message-renderer #event-text {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
yt-live-chat-legacy-paid-message-renderer #detail-text {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
yt-live-chat-paid-message-renderer {
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
margin: 8px 24px;
|
||||
font-size: 15px;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-ms-flex-direction: column;
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
yt-live-chat-paid-message-renderer #header {
|
||||
position: relative;
|
||||
font-weight: 500;
|
||||
padding: 8px 16px;
|
||||
min-height: 20px;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-ms-flex-direction: row;
|
||||
-webkit-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-ms-flex-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
|
||||
yt-live-chat-paid-message-renderer #header-content {
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-ms-flex-direction: column;
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-ms-flex-pack: justify;
|
||||
-webkit-justify-content: space-between;
|
||||
justify-content: space-between;
|
||||
-ms-flex: 1 1 0.000000001px;
|
||||
-webkit-flex: 1;
|
||||
flex: 1;
|
||||
-webkit-flex-basis: 0.000000001px;
|
||||
flex-basis: 0.000000001px;
|
||||
}
|
||||
|
||||
yt-live-chat-paid-message-renderer #author-photo {
|
||||
background-color: transparent;
|
||||
-ms-flex: none;
|
||||
-webkit-flex: none;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
yt-live-chat-paid-message-renderer #author-name {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
yt-live-chat-paid-message-renderer #content {
|
||||
padding: 4px 16px 8px 16px;
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
yt-live-chat-ticker-paid-message-item-renderer {
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
border-radius: 200px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
yt-live-chat-ticker-paid-message-item-renderer #content {
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-ms-flex-direction: row;
|
||||
-webkit-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-ms-flex-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
yt-live-chat-ticker-paid-message-item-renderer #fake-avatar {
|
||||
display: inline-block;
|
||||
background-color: red;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 4px;
|
||||
border-radius: 24px;
|
||||
|
||||
}
|
||||
|
||||
/* 以下为自动生成:https://chatv2.septapus.com/ */
|
||||
|
||||
@import url("https://fonts.googleapis.com/css?family=Changa One");
|
||||
@import url("https://fonts.googleapis.com/css?family=Imprima");
|
||||
|
||||
/* Background colors*/
|
||||
body {
|
||||
overflow: hidden;
|
||||
background-color: rgba(0,0,0,0);
|
||||
}
|
||||
/* Transparent background. */
|
||||
yt-live-chat-renderer {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
yt-live-chat-text-message-renderer,
|
||||
yt-live-chat-text-message-renderer[is-highlighted] {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer[author-type="owner"],
|
||||
yt-live-chat-text-message-renderer[author-type="owner"][is-highlighted] {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer[author-type="moderator"],
|
||||
yt-live-chat-text-message-renderer[author-type="moderator"][is-highlighted] {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer[author-type="member"],
|
||||
yt-live-chat-text-message-renderer[author-type="member"][is-highlighted] {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
|
||||
yt-live-chat-author-chip #author-name {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
/* Outlines */
|
||||
yt-live-chat-renderer * {
|
||||
text-shadow: -2px -2px #000000,-2px -1px #000000,-2px 0px #000000,-2px 1px #000000,-2px 2px #000000,-1px -2px #000000,-1px -1px #000000,-1px 0px #000000,-1px 1px #000000,-1px 2px #000000,0px -2px #000000,0px -1px #000000,0px 0px #000000,0px 1px #000000,0px 2px #000000,1px -2px #000000,1px -1px #000000,1px 0px #000000,1px 1px #000000,1px 2px #000000,2px -2px #000000,2px -1px #000000,2px 0px #000000,2px 1px #000000,2px 2px #000000;
|
||||
font-family: "Imprima";
|
||||
font-size: 18px !important;
|
||||
line-height: 18px !important;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer #content,
|
||||
yt-live-chat-legacy-paid-message-renderer #content {
|
||||
overflow: initial !important;
|
||||
}
|
||||
|
||||
/* Hide scrollbar. */
|
||||
yt-live-chat-item-list-renderer #items{
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
yt-live-chat-item-list-renderer #item-scroller{
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
/* Hide header and input. */
|
||||
yt-live-chat-header-renderer,
|
||||
yt-live-chat-message-input-renderer {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Reduce side padding. */
|
||||
yt-live-chat-text-message-renderer,
|
||||
yt-live-chat-legacy-paid-message-renderer {
|
||||
padding-left: 4px !important;
|
||||
padding-right: 4px !important;
|
||||
}
|
||||
|
||||
yt-live-chat-paid-message-renderer #header {
|
||||
padding-left: 4px !important;
|
||||
padding-right: 4px !important;
|
||||
}
|
||||
|
||||
/* Avatars. */
|
||||
yt-live-chat-text-message-renderer #author-photo,
|
||||
yt-live-chat-paid-message-renderer #author-photo,
|
||||
yt-live-chat-legacy-paid-message-renderer #author-photo {
|
||||
|
||||
width: 24px !important;
|
||||
height: 24px !important;
|
||||
border-radius: 24px !important;
|
||||
margin-right: 6px !important;
|
||||
}
|
||||
|
||||
/* Hide badges. */
|
||||
yt-live-chat-text-message-renderer #author-badges {
|
||||
display: none !important;
|
||||
vertical-align: text-top !important;
|
||||
}
|
||||
|
||||
/* Timestamps. */
|
||||
yt-live-chat-text-message-renderer #timestamp {
|
||||
|
||||
color: #999999 !important;
|
||||
font-family: "Imprima";
|
||||
font-size: 16px !important;
|
||||
line-height: 16px !important;
|
||||
}
|
||||
|
||||
/* Badges. */
|
||||
yt-live-chat-text-message-renderer #author-name[type="owner"],
|
||||
yt-live-chat-text-message-renderer yt-live-chat-author-badge-renderer[type="owner"] {
|
||||
color: #ffd600 !important;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer #author-name[type="moderator"],
|
||||
yt-live-chat-text-message-renderer yt-live-chat-author-badge-renderer[type="moderator"] {
|
||||
color: #5e84f1 !important;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer #author-name[type="member"],
|
||||
yt-live-chat-text-message-renderer yt-live-chat-author-badge-renderer[type="member"] {
|
||||
color: #0f9d58 !important;
|
||||
}
|
||||
|
||||
/* Channel names. */
|
||||
yt-live-chat-text-message-renderer #author-name {
|
||||
color: #cccccc !important;
|
||||
font-family: "Changa One";
|
||||
font-size: 20px !important;
|
||||
line-height: 20px !important;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer #author-name::after {
|
||||
content: ":";
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
/* Messages. */
|
||||
yt-live-chat-text-message-renderer #message,
|
||||
yt-live-chat-text-message-renderer #message * {
|
||||
color: #ffffff !important;
|
||||
font-family: "Imprima";
|
||||
font-size: 18px !important;
|
||||
line-height: 18px !important;
|
||||
}
|
||||
|
||||
|
||||
/* SuperChat/Fan Funding Messages. */
|
||||
yt-live-chat-paid-message-renderer #author-name,
|
||||
yt-live-chat-paid-message-renderer #author-name *,
|
||||
yt-live-chat-legacy-paid-message-renderer #event-text,
|
||||
yt-live-chat-legacy-paid-message-renderer #event-text * {
|
||||
color: #ffffff !important;
|
||||
font-family: "Changa One";
|
||||
font-size: 20px !important;
|
||||
line-height: 20px !important;
|
||||
}
|
||||
|
||||
yt-live-chat-paid-message-renderer #purchase-amount,
|
||||
yt-live-chat-paid-message-renderer #purchase-amount *,
|
||||
yt-live-chat-legacy-paid-message-renderer #detail-text,
|
||||
yt-live-chat-legacy-paid-message-renderer #detail-text * {
|
||||
color: #ffffff !important;
|
||||
font-family: "Imprima";
|
||||
font-size: 18px !important;
|
||||
line-height: 18px !important;
|
||||
}
|
||||
|
||||
yt-live-chat-paid-message-renderer #content,
|
||||
yt-live-chat-paid-message-renderer #content * {
|
||||
color: #ffffff !important;
|
||||
font-family: "Imprima";
|
||||
font-size: 18px !important;
|
||||
line-height: 18px !important;
|
||||
}
|
||||
|
||||
yt-live-chat-paid-message-renderer {
|
||||
margin: 4px 0 !important;
|
||||
}
|
||||
|
||||
yt-live-chat-legacy-paid-message-renderer {
|
||||
background-color: #0f9d58 !important;
|
||||
margin: 4px 0 !important;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer a,
|
||||
yt-live-chat-legacy-paid-message-renderer a {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer[is-deleted],
|
||||
yt-live-chat-legacy-paid-message-renderer[is-deleted] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
yt-live-chat-ticker-renderer {
|
||||
background-color: transparent !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
yt-live-chat-ticker-renderer {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
yt-live-chat-ticker-paid-message-item-renderer,
|
||||
yt-live-chat-ticker-paid-message-item-renderer *,
|
||||
yt-live-chat-ticker-sponsor-item-renderer,
|
||||
yt-live-chat-ticker-sponsor-item-renderer * {
|
||||
color: #ffffff !important;
|
||||
font-family: "Imprima";
|
||||
}
|
||||
|
||||
yt-live-chat-mode-change-message-renderer,
|
||||
yt-live-chat-viewer-engagement-message-renderer,
|
||||
yt-live-chat-restricted-participation-renderer {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
|
24
frontend/src/components/TextMessage.vue
Normal file
24
frontend/src/components/TextMessage.vue
Normal file
@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<yt-live-chat-text-message-renderer>
|
||||
<div id="author-photo">
|
||||
<img id="img" height="24" width="24" :src="avatarUrl" />
|
||||
</div>
|
||||
<div id="content">
|
||||
<span id="timestamp">{{time}}</span>
|
||||
<span id="author-name">{{authorName}}</span>
|
||||
<span id="message">{{content}}</span>
|
||||
</div>
|
||||
</yt-live-chat-text-message-renderer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TextMessage',
|
||||
props: {
|
||||
avatarUrl: String,
|
||||
time: String,
|
||||
authorName: String,
|
||||
content: String
|
||||
}
|
||||
}
|
||||
</script>
|
5
main.py
5
main.py
@ -5,6 +5,8 @@ import os
|
||||
import tornado.ioloop
|
||||
import tornado.web
|
||||
|
||||
import chat
|
||||
|
||||
WEB_ROOT = os.path.join(os.path.dirname(__file__), 'frontend', 'dist')
|
||||
|
||||
|
||||
@ -17,10 +19,11 @@ class MainHandler(tornado.web.StaticFileHandler):
|
||||
|
||||
def main():
|
||||
app = tornado.web.Application([
|
||||
(r'/chat', chat.ChatHandler),
|
||||
(r'/((css|img|js)/.*)', tornado.web.StaticFileHandler, {'path': WEB_ROOT}),
|
||||
(r'/(favicon\.ico)', tornado.web.StaticFileHandler, {'path': WEB_ROOT}),
|
||||
(r'/.*', MainHandler, {'path': WEB_ROOT})
|
||||
])
|
||||
], websocket_ping_interval=30)
|
||||
app.listen(80, '127.0.0.1')
|
||||
tornado.ioloop.IOLoop.current().start()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user