Устанавливаем
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)