Категория: Технология программирования

Кол-во просмотров: 5791

Теги: #python #django


реализация api очереди SockJS-Tornado на примере django

Устанавливаем 

pip install pushme django-cors-headers

в settings.py добавляем:

 

INSTALLED_APPS = (
    ....
    'corsheaders',
    ....
)
MIDDLEWARE_CLASSES = (
    'corsheaders.middleware.CorsMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'corsheaders.middleware.CorsMiddleware',
)


TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

CORS_ORIGIN_ALLOW_ALL = True

CORS_ALLOW_METHODS = (
        'GET',
        'POST',
        'PUT',
        'PATCH',
        'DELETE',
        'OPTIONS'
    )
CORS_ALLOW_HEADERS = (
        'x-requested-with',
        'content-type',
        'accept',
        'origin',
        'authorization',
        'x-csrftoken'
    )

 

реализация api:

views.py

 

try:
    import json
except ImportError:
    import simplejson as json

from django.http import HttpResponse, HttpResponseRedirect
from django.views.generic import View
from django.core.urlresolvers import reverse

from .helpers import encoder_fabric

from pushme.mq import get_sender


sender = get_sender(
    'snakemq',
    ('localhost', 4000)
)



class BaseView(View):

    def render_to_json_response(self, context, **response_kwargs):
        response_kwargs['content_type'] = 'application/json'
        if isinstance(context, str):
            return HttpResponse(context, **response_kwargs)
        return HttpResponse(
            json.dumps(context,
                       cls=encoder_fabric(self.request)),
            **response_kwargs
        )

    def redirect(self, reverse_name, args=None, **kwargs):
        return HttpResponseRedirect(reverse(reverse_name, args=args), **kwargs)

    def redirect_to_url(self, url, **kwargs):
        return HttpResponseRedirect(url, **kwargs)


class AsyncView(BaseView):
    """ Test view for async exchange
    """
    def dispatch(self, *args, **kwargs):
        return super(AsyncView, self).dispatch(*args, **kwargs)



    def post(self, request, *args, **kwargs):
        msg = request.POST.get('message')
        print('test')
        # uid - id пользователя получателя
        sender.send(data=msg, uid=1, topic='send-message')

        return self.render_to_json_response({'message': msg})

 

urls.py

url(r'^sendmsg', AsyncView.as_view())

 

теперь html

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title></title>

    <script type="text/javascript" src="static/jquery.js"></script>

    <script type="text/javascript" src="static/sockjs-0.3.min.js"></script>

    <script type="text/javascript" src="static/pushme.js"></script>

    <script type="text/javascript" src="static/other.js"></script>

    <script type="text/javascript">

        var baseUrl = 'http://10.20.2.10';



 

        pushMeConnection.connect(
            baseUrl, 9999, 1 // где 1 id текущего пользователя
        );

        $(document).ready(function(){
           var sender = $('form#send-message-form > input[type=button]');

            $.support.cors = true;
            $.support.cache = false;

            sender.on('click', function(){
                var form = $(this).parent(),
                    msg = form.find('input[type=text]').val();
                if(msg) {
                    $.ajax({
                        url: form.prop('action'),
                        crossDomain: true,
                        data: {'message': msg},
                        dataType: 'json',
                        type: 'post'
                    });
                }
            });
        });
    </script>
</head>
<body>
    <form method="post" id="send-message-form" action="http://10.20.2.10:8000/sendmsg">
        <h3>Send message:</h3>
        <input type="text" name="message"/>
        <input type="button" name="Send" value="Send message"/>
    </form>
</body>
</html>

 

в other.js

 


$(document).ready(function(){
   pushMeConnection.subscribe(function(msg, topic){
      if (topic == 'send-message' && !!msg && msg != '') {
         alert(msg);
      }
   });
});

 

в pushme.js

 

// клиентская сторона socket-соединения

var pushMeConnection = {

    conn: undefined,

    reconnectTimeout: 5000,

    listenerIdSeq: 1,

    listeners: {},
    callbacks: {},

    MAGIC_TOPIC: '-<*>-', 

    connect: function(host, port, uid) {
        var pushme = this;
        
        if (!this.conn) {
            var conn = new SockJS(host + ':' + port + '/pull');

            conn.onopen = function() { conn.send(uid); };

            conn.onmessage = function(msg) {
                pushme.processMessage(msg);
            };

            conn.onclose = function() {
                delete pushme.conn;
                var tOut = setTimeout(
                    function() {
                        clearTimeout(tOut);
                        pushme.connect(host, port, uid);
                    },
                    pushme.reconnectTimeout
                );
            };

            this.conn = conn;

        } else {
            console.error('Already connected!');
        };
    },

    processMessage: function(e) {
        var msg = JSON.parse(e.data),
            topic = msg.topic,
            fanouts = this.callbacks[this.MAGIC_TOPIC],
            handlers = this.callbacks[topic];

        for (var key in fanouts) {
            fanouts[key](msg.data, topic);
        };

        for (var key in handlers) {
            handlers[key](msg.data, topic);
        };
    },

    subscribe: function(callback, topic) {

        this.listenerIdSeq += 1;
        var id = this.listenerIdSeq,
            topic = topic || this.MAGIC_TOPIC;
        if (!this.callbacks[topic]) {
            this.callbacks[topic] = {}
        };
        this.callbacks[topic][id] = callback;
        this.listeners[id] = topic;
        return id;
    },

    unsubscribe: function(id) {
 
        if (this.listeners[id]) {
            delete this.callbacks[this.listeners[id]][id];
            delete this.listeners[id];
        } else {
            console.error('Wrong listener id:', id);
        };
    },
};

 

Стартуем


python manage.py rumserver 0.0.0.0:8000
python -m pushme.queue --host=localhost --port=4000
python -m pushme.server --host=10.20.2.10 --port=9999

Теперь запукаем две html, в одной id указываем 1 во второй id 2. 

При текущей реализации, если в html, где id=2 нажмем на кнопку Send message, то у запущенной html, где id = 1 появится alert(msg)

скачать файл sockjs-0.3.min.js

скачать файл jquery.js

Категория: Технология программирования

Кол-во просмотров: 5791

Дата создания: 29 августа 2016 г.

Теги: #python #django