djangoʵʱͨѶ--channels2.xʹÓÃ

2018-11-28 08:52:20À´Ô´£º²©¿ÍÔ° ÔĶÁ ()

ÐÂÀÏ¿Í»§´ó»ØÀ¡,ÔÆ·þÎñÆ÷µÍÖÁ5ÕÛ

Ò»¡¢±³¾°

¡¡¡¡ÔÚ×î½üµÄÏîÄ¿ÖеÄÒ»¸öÐèÇóÊÇÏûϢʵʱÍÆËÍÏûÏ¢ÒÔ¼°Í¨Öª¹¦ÄÜ£¬ÏîĿʹÓÃdjangoдµÄËùÒÔ¾ö¶¨²ÉÓÃdjango-channelsÀ´ÊµÏÖwebsocket½øÐÐʵʱͨѶ¡£Ä¿Ç°¹Ù·½ÒѾ­¸üе½2.1°æ±¾£¬Ïà¶ÔÓÚÀϵÄchannels 1.x°æ±¾ÓÐÁ˺ܴó±ä»¯£¬ÎÞÂÛÊÇʹÓ÷½Ê½»¹Êǹ¦ÄÜ£¬ÆäÖÐ×î´óµÄ±ä»¯Äª¹ýÓÚ2.x°æ±¾ÖдøÀ´µÄasyncioÌØÐÔ£¬¿ÉʹÓÃÒì²½´¦Àíģʽ¡£±¾ÎÄÄÚÈݽ«½éÉÜchannels2°æ±¾Ê¹Óã¬ÓÉÓÚÏîÄ¿djangoÊÇ1.11,ÆäÖÐÒ²Óöµ½ÁËһЩ¿Ó£¬±ÈÈçÔÚchannelsÔÚ´¦ÀíÒ»´ÎÇëÇóºóhangסȻºó±¨´í£¬ºóÃæÐÞ¸ÄÁËÏÂdjango1.11°æ±¾µÄÒ»µãÔ´ÂëµÃÒÔ½â¾ö£¬2.0°æ±¾Ó¦¸Ã²»»áÓÐÎÊÌâ¡£

¶þ¡¢channels½éÉÜ

¡¡¡¡channelsÊÇÒÔdjango²å¼þµÄÐÎʽ´æÔÚ£¬Ëü²»½öÄÜ´¦ÀíhttpÇëÇ󣬻¹Ìṩ¶Ôwebsocket¡¢MQTTµÈ³¤Á¬½ÓÖ§³Ö¡£²»½öÈç´Ë£¬channelsÔÚ±£ÁôÁËÔ­ÉúdjangoµÄͬ²½ºÍÒ×ÓõÄÌØÐÔÉÏ»¹´øÀ´ÁËÒì²½´¦Àí·½Ê½(channels2.X°æ±¾)£¬²¢ÇÒ½«django×Ô´øµÄÈÏ֤ϵͳÒÔ¼°session¼¯³Éµ½Ä£¿éÖУ¬À©Õ¹ÐԷdz£Ç¿¡£¹Ù·½Îĵµ£ºhttps://channels.readthedocs.io/en/latest/index.html

 

Èý¡¢°²×°ÒÔ¼°°²×°ÐèÇó

¡¡¡¡channels2.0×îµÍdjango°æ±¾ÒªÇóÊÇ1.11+£¬python3.5+¡£±ÊÕߵİ汾ÊÇdjango1.11£¬Ö±½Ó°²×°¿ÉÄÜÓÐÎÊÌ⣬ÒÔÏÂÊDzâÊÔͨ¹ýµÄ°æ±¾¡£

±ÊÕßµÄÏà¹Ø°æ±¾ÈçÏ£º

Django==1.11.10
channels==2.1.4
channels-redis==2.3.1
asgiref==2.1.6
asgi-redis==1.4.3

Èç¹ûdjango°æ±¾±È½Ï¸ßÖ±½Ó²ÉÓÃpip°²×°£º

pip3 install channels
pip3 install channels-redis  #¿ÉÑ¡µÄ£¬¹Ù·½ÍƼöÈç¹ûʹÓÃredis×÷Ϊchannel layer

redis°²×°¿ÉÒԲο¼²©¿Í£ºhttps://www.cnblogs.com/wdliu/p/9360286.html

ËÄ¡¢¿ªÊ¼Ê¹ÓÃ

Ò»¡¢ÅäÖÃsettings.py

¡¡¡¡±ÊÕß²ÉÓõÄredis×÷Ϊchannel layer(¹ØÓÚÆä½éÉÜÇëÒƲ½ÖÁhttps://channels.readthedocs.io/en/latest/topics/channel_layers.html),ËüÊÇʵÏÖÏûÏ¢ÍÆË͵ĺËÐÄ£¬ÔÚÏîÄ¿µÄsettings.pyÖУº

×¢²áchannles app£º

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'cmdb',
    'channels', #×¢²áapp
]

ÅäÖÃchannels layer£º

ASGI_APPLICATION = 'devops.routing.application'
CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('10.1.210.33', 6379)], #ÐèÐÞ¸Ä
        },
    },
}

 

¶þ¡¢Â·ÓÉÅäÖÃ

ÔÚÏîÄ¿settingsÎļþͬ¼¶Ä¿Â¼ÖÐÐÂÔörouting.py

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Author:wd

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import deploy.routing

application = ProtocolTypeRouter({
    'websocket': AuthMiddlewareStack(
        URLRouter(
            deploy.routing.websocket_urlpatterns# Ö¸Ã÷·ÓÉÎļþÊÇdevops/routing.py
        )
    ),
})

×îºóÔÚappÀïÅäÖ÷ÓɺͶÔÓ¦µÄÏû·ÑÕߣ¬±ÊÕßÕâÀïÊÇdevopsϵÄrouting.py£º

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Author:wd
from django.conf.urls import url

from . import consumers

websocket_urlpatterns = [
    url(r'^ws/deploy/(?P<service_name>[^/]+)/$', consumers.DeployResult), #consumers.DeployResult ÊǸ÷ÓɵÄÏû·ÑÕß
]

ÏîĿĿ¼½á¹¹ÈçÏ£º

 

 

Èý¡¢±àдwebscoketÏûÏ¢´¦Àí·½·¨(Ïû·ÑÕß)

Ê×ÏÈ˵Ã÷£¬Ïû·ÑÕßÊÇChannels´úÂëµÄ»ù±¾µ¥Ôª£¬µ±Ò»¸öеÄSocket½øÈëµÄʱºò£¬Channels»á¸ù¾Ý·ÓɱíÕÒµ½ÕýÈ·µÄÏû·ÑÕߣ¬ÒÔÏ´úÂëÖÐÿ¸ö·½·¨¶¼¿ÉÒÔ¿´×÷Ò»¸öÏû·ÑÕߣ¬ËûÃÇÏû·Ñ²»Í¬µÄevent£¬±ÈÈç¸Õ¸Õ½ÓÊÜÁ¬½Óʱºòconnect·½·¨½øÐÐÏû·Ñ´¦Àí²¢½ÓÊÜÁ¬½Ó£¬¹Ø±ÕwebsocketʱºòʹÓÃdisconnect½øÐÐÏû·Ñ´¦Àí¡£

deploy/consumers.py£º

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Author:wd

from channels.generic.websocket import AsyncWebsocketConsumer
import json

class DeployResult(AsyncWebsocketConsumer):
    async def connect(self):
        self.service_uid = self.scope["url_route"]["kwargs"]["service_uid"]
        self.chat_group_name = 'chat_%s' % self.service_uid
        # ÊÕµ½Á¬½Óʱºò´¦Àí£¬
        await self.channel_layer.group_add(
            self.chat_group_name,
            self.channel_name
        )

        await self.accept()

    async def disconnect(self, close_code):
        # ¹Ø±Õchannelʱºò´¦Àí
        await self.channel_layer.group_discard(
            self.chat_group_name,
            self.channel_name
        )

    # ÊÕµ½ÏûÏ¢
    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
        print("ÊÕµ½ÏûÏ¢--¡·",message)
        # ·¢ËÍÏûÏ¢µ½×é
        await self.channel_layer.group_send(
            self.chat_group_name,
            {
                'type': 'client.message',
                'message': message
            }
        )

    # ´¦Àí¿Í»§¶Ë·¢À´µÄÏûÏ¢
    async def client_message(self, event):
        message = event['message']
        print("·¢ËÍÏûÏ¢¡£¡£¡£",message)
        # ·¢ËÍÏûÏ¢µ½ WebSocket
        await self.send(text_data=json.dumps({
            'message': message
        }))

ÒÔÉÏ´úÂ벿·Ö˵Ã÷£º

1.self.scopeÊǵ¥¸öÁ¬½Ó´«ÈëµÄÏêϸÐÅÏ¢£¬ÆäÖаüº¬ÁËÇëÇóµÄsession¡¢ÒÔ¼°djangoÈÏ֤ϵͳÖеÄÓû§ÐÅÏ¢µÈ£»

2.async...await ÊÇpython3.5Ö®ºóµÄÐÂÒì²½ÌØÐÔ£¬»ùÓÚasyncioÄ£¿é£»

ËÄ¡¢·¢ÆðwebscoketÇëÇó

ÀûÓÃjs·¢ÆðwebsocketÇëÇó

function InitWebSocket() {
            var websocket = new WebSocket( 
                'ws://' + window.location.host + '/ws/deploy/tasks/' );

            websocket.onmessage = function (e) {
                var data = JSON.parse(e.data);
                var message = '\n' + data['message'];
                document.querySelector('#deploy-res').innerText += (message + '\n');
            };
        }

 

Îå¡¢·¢ËÍÏûÏ¢µ½channel

ÎÞÂÛÊÇÏûÏ¢µÄÍÆËÍ»òÕßÏûÏ¢µÄ½ÓÊÜ£¬¶¼ÊǾ­¹ýchannel layer½øÐд«Ê䣬ÒÔÏÂÊÇ·¢ËÍÏûϢʾÀý£¬

from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync


channel_layer = get_channel_layer()
def send_channel_msg(channel_name, msg):
     """
        send msg to channel
        :param channel_name: 
        :param msg: 
        :return: 
        """
    async_to_sync(channel_layer.group_send)(channel_name,
                                                 {"type": "deploy.run", "text": msg})

Áù¡¢Éú²ú²¿Êð

´ó¶àÊýdjangoµÄÓ¦Óò¿Êð·½Ê½¶¼²ÉÓõÄÊÇnginx+uwsgi½øÐв¿Ê𣬵±django¼¯³Échannelsʱºò£¬ÓÉÓÚuwsgi²»ÄÜ´¦ÀíwebsocketÇëÇó£¬ËùÒÔÎÒÃÇÐèÒªasgi·þÎñÆ÷À´´¦ÀíwebsocketÇëÇ󣬹ٷ½ÍƼöʹÓÃdaphne¡£ÏÂһƪÎÄÕ½«½éÉÜnginx+supervisor+daphne+uwsgi½øÐÐÉú²ú²¿Êð¡£

 

  

±êÇ©£º

°æȨÉêÃ÷£º±¾Õ¾ÎÄÕ²¿·Ö×ÔÍøÂ磬ÈçÓÐÇÖȨ£¬ÇëÁªÏµ£ºwest999com@outlook.com
Ìرð×¢Ò⣺±¾Õ¾ËùÓÐתÔØÎÄÕÂÑÔÂÛ²»´ú±í±¾Õ¾¹Ûµã£¬±¾Õ¾ËùÌṩµÄÉãÓ°ÕÕƬ£¬²å»­£¬Éè¼Æ×÷Æ·£¬ÈçÐèʹÓã¬ÇëÓëÔ­×÷ÕßÁªÏµ£¬°æȨ¹éÔ­×÷ÕßËùÓÐ

ÉÏһƪ£ºcentos6£¬python3£¬Í¨¹ýpip°²×°pycurl³öÏÖ±¨´íÌáʾ

ÏÂһƪ£ºPython»ù´¡---Áбí