django channels websocket 聊天室

基础项目部署参考:点击打开链接


1、下载相应插件:

pip install channels
pip install asgi_redis



2、部署基本项目:



3、目录结构如下:

django channels websocket 聊天室_第1张图片



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


  
{% csrf_token %} {% for field in form %}
{{ field.label_tag }} {{ field }}
{% endfor %}

Don't have an account? Sign up!




14、sign_up.html :





Insert title here


{% block content %}
  
{% csrf_token %} {% for field in form %}
{{ field.label_tag }} {{ field }}
{% endfor %}

Already have an account? Log in!

{% 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;
}


你可能感兴趣的:(Python)