2014-05-04 17:26:43 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2014-09-02 22:32:44 +00:00
|
|
|
|
2014-05-04 17:26:43 +00:00
|
|
|
|
|
|
|
from tornado.websocket import WebSocketHandler
|
|
|
|
from tornado.ioloop import IOLoop
|
|
|
|
import json
|
|
|
|
|
2014-05-21 22:41:29 +00:00
|
|
|
from oxtornado import json_dumps
|
2014-05-04 17:26:43 +00:00
|
|
|
|
|
|
|
import state
|
2015-12-02 21:05:23 +00:00
|
|
|
import settings
|
2014-05-04 17:26:43 +00:00
|
|
|
|
2014-05-18 03:01:24 +00:00
|
|
|
import logging
|
2015-11-29 14:56:38 +00:00
|
|
|
logger = logging.getLogger(__name__)
|
2014-05-17 14:26:59 +00:00
|
|
|
|
2014-05-04 17:26:43 +00:00
|
|
|
|
|
|
|
class Handler(WebSocketHandler):
|
|
|
|
|
2019-01-17 10:30:22 +00:00
|
|
|
def initialize(self, public=False):
|
|
|
|
self._public = public
|
|
|
|
|
2014-08-12 12:51:38 +00:00
|
|
|
def check_origin(self, origin):
|
|
|
|
# allow access to websocket from site, installer and loader (local file)
|
2015-11-02 11:14:44 +00:00
|
|
|
return self.request.host in origin or \
|
2015-11-02 23:29:16 +00:00
|
|
|
origin in (
|
|
|
|
'http://127.0.0.1:9841',
|
|
|
|
'http://127.0.0.1:9842',
|
2015-11-03 17:32:53 +00:00
|
|
|
'file://',
|
2015-11-02 23:29:16 +00:00
|
|
|
'null'
|
|
|
|
)
|
2014-08-12 12:51:38 +00:00
|
|
|
|
2014-05-04 17:26:43 +00:00
|
|
|
def open(self):
|
2016-01-17 15:00:19 +00:00
|
|
|
if self.request.headers['origin'] not in ('null', 'file://', 'http://127.0.0.1:9842') \
|
2014-08-12 12:51:38 +00:00
|
|
|
and self.request.host not in self.request.headers['origin']:
|
2014-05-17 14:26:59 +00:00
|
|
|
logger.debug('reject cross site attempt to open websocket %s', self.request)
|
2014-05-14 09:57:11 +00:00
|
|
|
self.close()
|
2014-05-26 11:21:19 +00:00
|
|
|
if self not in state.websockets:
|
|
|
|
state.websockets.append(self)
|
2016-01-13 06:47:13 +00:00
|
|
|
if state.update:
|
2016-02-12 12:53:02 +00:00
|
|
|
trigger_event('updatestatus', state.update._status)
|
2016-01-13 06:47:13 +00:00
|
|
|
else:
|
2016-01-31 16:44:00 +00:00
|
|
|
from user.models import User
|
2016-01-13 06:47:13 +00:00
|
|
|
trigger_event('status', {
|
|
|
|
'id': settings.USER_ID,
|
|
|
|
'online': state.online
|
|
|
|
})
|
2016-01-31 16:44:00 +00:00
|
|
|
for u in User.query.filter(User.id!=settings.USER_ID).filter_by(peered=True).all():
|
|
|
|
u.trigger_status()
|
2014-05-04 17:26:43 +00:00
|
|
|
|
|
|
|
#websocket calls
|
|
|
|
def on_message(self, message):
|
2019-02-02 07:27:46 +00:00
|
|
|
try:
|
|
|
|
action, data = json.loads(message)
|
|
|
|
except json.decoder.JSONDecodeError:
|
|
|
|
logger.debug('invalid websocket message: %s', message)
|
|
|
|
return
|
2014-05-26 11:21:19 +00:00
|
|
|
if state.tasks:
|
|
|
|
state.tasks.queue(action, data)
|
2014-05-04 17:26:43 +00:00
|
|
|
|
|
|
|
def on_close(self):
|
2014-05-26 11:21:19 +00:00
|
|
|
if self in state.websockets:
|
|
|
|
state.websockets.remove(self)
|
|
|
|
|
|
|
|
def post(self, event, data):
|
|
|
|
message = json_dumps([event, data])
|
2015-11-17 18:23:21 +00:00
|
|
|
if self.ws_connection is None:
|
|
|
|
self.on_close()
|
|
|
|
else:
|
2019-02-02 07:27:46 +00:00
|
|
|
state.main.add_callback(lambda: self._write_message(message))
|
|
|
|
|
|
|
|
async def _write_message(self, message):
|
|
|
|
try:
|
|
|
|
task = self.write_message(message)
|
|
|
|
await task
|
|
|
|
except tornado.iostream.StreamClosedError as e:
|
|
|
|
self.on_close()
|
|
|
|
except tornado.websocket.WebSocketClosedError as e:
|
|
|
|
self.on_close()
|
|
|
|
|
2014-05-04 17:26:43 +00:00
|
|
|
|
|
|
|
def trigger_event(event, data):
|
2016-02-23 18:00:56 +00:00
|
|
|
#if len(state.websockets):
|
|
|
|
# logger.debug('trigger event %s %s %s', event, data, len(state.websockets))
|
2014-05-04 17:26:43 +00:00
|
|
|
for ws in state.websockets:
|
|
|
|
try:
|
2014-05-26 11:21:19 +00:00
|
|
|
ws.post(event, data)
|
2014-05-04 17:26:43 +00:00
|
|
|
except:
|
2016-01-24 09:13:03 +00:00
|
|
|
logger.debug('failed to send to ws %s %s %s', ws, event, data, exc_info=True)
|