基础项目部署参考:点击打开链接
1、下载相应插件:
pip install channels
pip install asgi_redis
3、目录结构如下:
4、setting py 增加配置:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'channels',
'demo',
]
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'asgi_redis.RedisChannelLayer',
'CONFIG': {
'hosts': [('127.0.0.1', 6379)],
},
'ROUTING': 'busymonkey.routing.channel_routing',
}
}
5、routing py :
from channels.routing import route
from demo.consumers import ws_connect, ws_disconnect, ws_receive
channel_routing = [
route('websocket.connect', ws_connect),
route("websocket.receive", ws_receive),
route('websocket.disconnect', ws_disconnect),
]
6、comsumers py :
import json
from channels import Group
from channels.auth import channel_session_user, channel_session_user_from_http
@channel_session_user_from_http
def ws_connect(message):
groupPath = message.content['path'][1:-1]
Group(groupPath).add(message.reply_channel)
Group(groupPath).send({
'text': json.dumps({
'username': message.user.username,
'is_logged_in': True
})
})
def ws_receive(message):
groupPath = message.content['path'][1:-1]
Group(groupPath).send({
'text': json.dumps({
'content': message.content['text'],
})
})
@channel_session_user
def ws_disconnect(message):
groupPath = message.content['path'][1:-1]
Group(groupPath).send({
'text': json.dumps({
'username': message.user.username,
'is_logged_in': False
})
})
Group(groupPath).discard(message.reply_channel)
7、urls py :
from django.conf.urls import url
from django.contrib import admin
from demo import views as demo_views
urlpatterns = [
url(r'^user_list/$', demo_views.user_list, name='user_list'),
url(r'^log_in/$', demo_views.log_in, name='log_in'),
url(r'^log_out/$', demo_views.log_out, name='log_out'),
url(r'^sign_up/$', demo_views.sign_up, name='sign_up'),
url(r'^admin/', admin.site.urls),
]
8、wsgi py :
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "busymonkey.settings")
application = get_wsgi_application()
9、apps py :
from __future__ import unicode_literals
from django.apps import AppConfig
class DemoConfig(AppConfig):
name = 'demo'
def ready(self):
import demo.signals
10、models.py :
from __future__ import unicode_literals
from django.conf import settings
from django.db import models
# Create your models here.
class LoggedInUser(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL, related_name='logged_in_user')
11、signals.py :
from django.contrib.auth import user_logged_in, user_logged_out
from django.dispatch import receiver
from demo.models import LoggedInUser
@receiver(user_logged_in)
def on_user_login(sender, **kwargs):
LoggedInUser.objects.get_or_create(user=kwargs.get('user'))
@receiver(user_logged_out)
def on_user_logout(sender, **kwargs):
LoggedInUser.objects.filter(user=kwargs.get('user')).delete()
12、views.py :
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
# Create your views here.
from django.contrib.auth import get_user_model, login, logout
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
from django.shortcuts import redirect, render
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
User = get_user_model()
@login_required(login_url='/log_in/')
def user_list(request):
"""
NOTE: This is fine for demonstration purposes, but this should be
refactored before we deploy this app to production.
Imagine how 100,000 users logging in and out of our app would affect
the performance of this code!
"""
name = request.session.get('user', False)
users = User.objects.select_related('logged_in_user')
for user in users:
user.status = 'Online' if hasattr(user, 'logged_in_user') else 'Offline'
return render(request, 'user_list.html', {'users': users, 'user': name})
def log_in(request):
form = AuthenticationForm()
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
login(request, form.get_user())
request.session['user'] = form.get_user().__str__()
return redirect(reverse('user_list'))
else:
print(form.errors)
return render(request, 'log_in.html', {'form': form})
@login_required(login_url='/log_in/')
def log_out(request):
logout(request)
return redirect(reverse('log_in'))
def sign_up(request):
form = UserCreationForm()
if request.method == 'POST':
form = UserCreationForm(data=request.POST)
if form.is_valid():
form.save()
return redirect(reverse('log_in'))
else:
print(form.errors)
return render(request, 'sign_up.html', {'form': form})
13、log_in.html :
Insert title here
Don't have an account? Sign up!
14、sign_up.html :
Insert title here
{% block content %}
{% endblock content %}
15、user_list.html:
Insert title here
Log out
userName : {{ user }}
{% for user in users %}
-
{{ user.username|escape }}: {{ user.status|default:'Offline' }}
{% endfor %}
16、 loginJS:
/**
* Created by Hou on 2017/4/10.
*/
function EventTrigger() {
}
EventTrigger.prototype.init = function () {
var socket = new WebSocket('ws://' + window.location.host + '/open/');
$("#openChatRoomBtn").click(function() {
var text = $("#chatName").val();
socket = new WebSocket('ws://' + window.location.host + '/'+ text +'/');
socket.onopen();
});
socket.onopen = function open() {
console.log('WebSockets connection created.');
};
socket.onmessage = function message(event) {
var data = JSON.parse(event.data);
// NOTE: We escape JavaScript to prevent XSS attacks.
var username = encodeURI(data['username']);
var content = data['content'];
var user = $('li').filter(function () {
return $(this).data('username') == username;
});
if (data['is_logged_in']) {
user.html(username + ': Online');
}
else {
user.html(username + ': Offline');
}
if (content != null && content != "") {
var text = $("#chatWin").val();
$("#chatWin").val(text+"\r\n"+content);
}
};
if (socket.readyState == WebSocket.OPEN) {
socket.onopen();
}
$("#sendBtn").click(function() {
var text = $("#sendInput").val();
socket.send(text);
});
}
17、loginCSS:
.Alert-Pwd-Error {
display: none;
position: absolute;
left: 50px;
top: 200px;
}
.Login-Body {
overflow-x: hidden;
margin-left: -15px;
margin-right: -15px;
}
.Login-Input {
height: 55px;
border-radius: 20px;
}
.Login-Input-Btn {
height: 50px;
width: 150px;
border-radius: 10px;
}
.Form-Div {
margin: 0 50px 0 50px;
}