您的位置:首页 > 编程语言 > Go语言

django channels websocket 聊天室

2017-08-07 15:26 435 查看
基础项目部署参考:点击打开链接

1、下载相应插件:

pip install channels
pip install asgi_redis


2、部署基本项目:

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 :

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="{% url 'log_in' %}" method="post">
{% csrf_token %}
{% for field in form %}
<div>
{{ field.label_tag }}
{{ field }}
</div>
{% endfor %}
<button type="submit">Log in</button>
</form>
<p>Don't have an account? <a href="{% url 'sign_up' %}">Sign up!</a></p>
</body>
</html>

14、sign_up.html :

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
{% block content %}
<form action="{% url 'sign_up' %}" method="post">
{% csrf_token %}
{% for field in form %}
<div>
{{ field.label_tag }}
{{ field }}
</div>
{% endfor %}
<button type="submit">Sign up</button>
<p>Already have an account? <a href="{% url 'log_in' %}">Log in!</a></p>
</form>
{% endblock content %}
</body>
</html>

15、user_list.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="/static/js/jquery-3.1.1.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
<script src="/static/js/loginJS.js"></script>
</head>
<script>
$(document).ready(function () {
var test = new EventTrigger();
test.init();
})

</script>
<body>
<a href="{% url 'log_out' %}">Log out</a>
<p id="userName">userName : {{ user }}</p>
<br>
<ul>
{% for user in users %}
<!-- NOTE: We escape HTML to prevent XSS attacks. -->
<li data-username="{{ user.username|escape }}">
{{ user.username|escape }}: {{ user.status|default:'Offline' }}
</li>
{% endfor %}
</ul>
<textarea id="chatWin" rows="20" cols="100"> </textarea>
<input id="chatName" type="text" />
<button id="openChatRoomBtn" type="button" >open chat room</button>
<input id="sendInput" type="text" />
<button id="sendBtn" type="button" >send</button>
</body>
</html>

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: