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