pip install redis tornado-redis pip install tornadio2 pip install sockjs-tornado .
on_message
method on_message
mandatory for implementation, but in the example above, it is not needed, because everything is implemented on a newfangled event model (for socket.io). # -*- coding: utf-8 -*- import tornado import tornadoredis from tornadio2 import SocketConnection from tornadio2.conn import event import django from django.utils.importlib import import_module from django.conf import settings from django.utils import simplejson # start of kmike's sources _engine = import_module(settings.SESSION_ENGINE) def get_session(session_key): return _engine.SessionStore(session_key) def get_user(session): class Dummy(object): pass django_request = Dummy() django_request.session = session return django.contrib.auth.get_user(django_request) # end of kmike's sources # redis django ORDERS_REDIS_HOST = getattr(settings, 'ORDERS_REDIS_HOST', 'localhost') ORDERS_REDIS_PORT = getattr(settings, 'ORDERS_REDIS_PORT', 6379) ORDERS_REDIS_PASSWORD = getattr(settings, 'ORDERS_REDIS_PASSWORD', None) ORDERS_REDIS_DB = getattr(settings, 'ORDERS_REDIS_DB', None) # unjson = simplejson.loads json = simplejson.dumps class Connection(SocketConnection): def __init__(self, *args, **kwargs): super(Connection, self).__init__(*args, **kwargs) self.listen_redis() @tornado.gen.engine def listen_redis(self): """ . """ self.redis_client = tornadoredis.Client( host=ORDERS_REDIS_HOST, port=ORDERS_REDIS_PORT, password=ORDERS_REDIS_PASSWORD, selected_db=ORDERS_REDIS_DB ) self.redis_client.connect() yield tornado.gen.Task(self.redis_client.subscribe, [ 'order_lock', 'order_done' ]) self.redis_client.listen(self.on_redis_queue) # # self.on_redis_queue def on_open(self, info): """ django. """ self.django_session = get_session(info.get_cookie('sessionid').value) @event # , def login(self): """ """ # , on_open self.user = get_user(self.django_session) self.is_client = self.user.has_perm('order.lock') self.is_moder = self.user.has_perm('order.delete') def on_message(self): """ . """ pass def on_redis_queue(self, message): """ """ if message.kind == 'message': # , # , message_body = unjson(message.body) # , # JSON # if message.channel == 'order_lock': self.on_lock(message_body) if message.channel == 'order_done: self.on_done(message_body) def on_lock(self, message): """ """ if message['user'] != self.user.pk: # - self.emit('lock', message) def on_done(self, message): """ """ if message['user'] != self.user.pk: if self.is_client: message['action'] = 'hide' else: message['action'] = 'highlight' self.emit('done', message) def on_close(self): """ """ self.redis_client.unsubscribe([ 'order_lock', 'order_done' ]) self.redis_client.disconnect()
# -*- coding: utf-8 -*- import tornado import tornadoredis from sockjs.tornado import SockJSConnection import django from django.utils.importlib import import_module from django.conf import settings from django.utils import simplejson # start of kmike's sources _engine = import_module(settings.SESSION_ENGINE) def get_session(session_key): return _engine.SessionStore(session_key) def get_user(session): class Dummy(object): pass django_request = Dummy() django_request.session = session return django.contrib.auth.get_user(django_request) # end of kmike's sources # redis django ORDERS_REDIS_HOST = getattr(settings, 'ORDERS_REDIS_HOST', 'localhost') ORDERS_REDIS_PORT = getattr(settings, 'ORDERS_REDIS_PORT', 6379) ORDERS_REDIS_PASSWORD = getattr(settings, 'ORDERS_REDIS_PASSWORD', None) ORDERS_REDIS_DB = getattr(settings, 'ORDERS_REDIS_DB', None) # unjson = simplejson.loads json = simplejson.dumps class Connection(SocketConnection): def __init__(self, *args, **kwargs): super(Connection, self).__init__(*args, **kwargs) self.listen_redis() @tornado.gen.engine def listen_redis(self): """ . """ self.redis_client = tornadoredis.Client( host=ORDERS_REDIS_HOST, port=ORDERS_REDIS_PORT, password=ORDERS_REDIS_PASSWORD, selected_db=ORDERS_REDIS_DB ) self.redis_client.connect() yield tornado.gen.Task(self.redis_client.subscribe, [ 'order_lock', 'order_done' ]) self.redis_client.listen(self.on_redis_queue) # # self.on_redis_queue def send(self, msg_type, message): """ . """ return super(Connection, self).send({ 'type': msg_type, 'data': message, }) def on_open(self, info): """ django. """ self.django_session = get_session(info.get_cookie('sessionid').value) self.user = get_user(self.django_session) self.is_client = self.user.has_perm('order.lock') self.is_moder = self.user.has_perm('order.delete') def on_message(self): """ . """ pass def on_redis_queue(self, message): """ """ if message.kind == 'message': # , # , message_body = unjson(message.body) # , # JSON # if message.channel == 'order_lock': self.on_lock(message_body) if message.channel == 'order_done: self.on_done(message_body) def on_lock(self, message): """ """ if message['user'] != self.user.pk: # - self.send('lock', message) def on_done(self, message): """ """ if message['user'] != self.user.pk: if self.is_client: message['action'] = 'hide' else: message['action'] = 'highlight' self.send('done', message) def on_close(self): """ """ self.redis_client.unsubscribe([ 'order_lock', 'order_done' ]) self.redis_client.disconnect()
# -*- coding: utf-8 -*- import redis from django.conf import settings from django.db import models ORDERS_FREE_LOCK_TIME = getattr(settings, 'ORDERS_FREE_LOCK_TIME', 0) ORDERS_REDIS_HOST = getattr(settings, 'ORDERS_REDIS_HOST', 'localhost') ORDERS_REDIS_PORT = getattr(settings, 'ORDERS_REDIS_PORT', 6379) ORDERS_REDIS_PASSWORD = getattr(settings, 'ORDERS_REDIS_PASSWORD', None) ORDERS_REDIS_DB = getattr(settings, 'ORDERS_REDIS_DB', 0) # service_queue = redis.StrictRedis( host=ORDERS_REDIS_HOST, port=ORDERS_REDIS_PORT, db=ORDERS_REDIS_DB, password=ORDERS_REDIS_PASSWORD ).publish json = simplejson.dumps class Order(models.Model) … def lock(self): """ """ … service_queue('order_lock', json({ 'user': self.client.pk, 'order': self.pk, })) def done(self): """ """ … service_queue('order_done', json({ 'user': self.client.pk, 'order': self.pk, }))
lock
and done
methods after executing some business logic send messages with the necessary information. This information will be obtained by the above service, processed and sent to client browsers. var socket = io.connect('http://' + window.location.host + ':8989'); // // login, socket.on('connect', function(){ socket.emit('login'); }); // - socket.on('disconnect', function() { setTimeout(socket.socket.reconnect, 5000); }); // "lock" "ws_order_lock" socket.on('lock', function(msg){ ws_order_lock(msg); }); socket.on('done', function(msg){ ws_order_done(msg); }); function ws_order_lock(msg){ if (msg.action == 'highlight'){ $('.id_order_row__' + msg.order).addClass('order-row_is_locked'); }else{ $('.id_info_renew_orders').addClass('hidden'); } } …
socket_connect(); function socket_connect() { socket = new SockJS('http://' + window.location.host + ':8989/orders'); // // login, socket.onmessage = function(msg){ window['ws_order_' + msg.data.type](msg.data.data); // , } socket.onclose = function(e){ setTimeout(socket_connect, 5000); }; } function ws_order_lock(msg){ if (msg.action == 'highlight'){ $('.id_order_row__' + msg.order).addClass('order-row_is_locked'); }else{ $('.id_info_renew_orders').addClass('hidden'); } } …
myProject/orderApp/management/commands
folder. Also, do not forget, in each of the subfolders, the __init__.py
file. # -*- coding: utf-8 -*- import tornado import tornadio2 as tornadio from django.core.management.base import NoArgsCommand from myProject.order.tornado.service import Connection class Command(NoArgsCommand): def handle_noargs(self, **options): router = tornadio.TornadioRouter(Connection) app = tornado.web.Application(router.urls, socket_io_port=8989) # tornadio.SocketServer(app)
# -*- coding: utf-8 -*- import tornado import tornadio2 as tornadio from django.core.management.base import NoArgsCommand from myProject.order.tornado.service import Connection class Command(NoArgsCommand): def handle_noargs(self, **options): router = SockJSRouter(Connection, '/orders') # sockjs :( app = tornado.web.Application(router.urls) app.listen(8989) tornado.ioloop.IOLoop.instance().start()
python manage.py async_server
.Source: https://habr.com/ru/post/128562/
All Articles