Отправка данных в группы каналов Django через представления Django - PullRequest
0 голосов
/ 26 сентября 2018

TL; DR

Хотите этот поток:

                     ws://...
websocket client 1 <-----------> websocket client 2
                         ^
                         |
                       server (send messages via views)

Итак, у меня есть следующее:

views.py

def alarm(request):
    layer = get_channel_layer()
    async_to_sync(layer.group_send)('events', {
    'type': 'events.alarm',
    'content': 'triggered'
    })
    return HttpResponse('<p>Done</p>')

consumer.py

class EventConsumer(JsonWebsocketConsumer):
  def connect(self):
    print('inside EventConsumer connect()')
    async_to_sync(self.channel_layer.group_add)(
        'events',
        self.channel_name
    )
    self.accept()

  def disconnect(self, close_code):
    print('inside EventConsumer disconnect()')
    print("Closed websocket with code: ", close_code)
    async_to_sync(self.channel_layer.group_discard)(
        'events',
        self.channel_name
    )
    self.close()

  def receive_json(self, content, **kwargs):
    print('inside EventConsumer receive_json()')
    print("Received event: {}".format(content))
    self.send_json(content)

  def events_alarm(self, event):
    print('inside EventConsumer events_alarm()')
    self.send_json(
        {
            'type': 'events.alarm',
            'content': event['content']
        }
    )

в routing.py

application = ProtocolTypeRouter({
    'websocket': AllowedHostsOriginValidator(
        AuthMiddlewareStack(
            URLRouter(
                chat.routing.websocket_urlpatterns,

            )
        )
    ),
})

, где websocket_urlpatterns равно

websocket_urlpatterns = [
url(r'^ws/chat/(?P<room_name>[^/]+)/$', consumers.ChatConsumer),
url(r'^ws/event/$', consumers.EventConsumer),
]

urls.py

urlpatterns = [
    url(r'^alarm/$', alarm, name='alarm'),
]

когда я звоню /alarm/, выполняется только HTTP-запрос, и сообщение не отправляется на веб-сокет

Следующие журналы:

[2018/09/26 18:59:12] HTTP GET /alarm/ 200 [0.07, 127.0.0.1:60124]

Мое намерениесделать так, чтобы django view отправлял группе (вариант использования - сервер отправлял бы уведомление всем подключенным членам в группе).

Какие настройки мне здесь не хватает.

Я работаюДжанго каналы 2.1.3 с Redis в качестве бэкэнда.CHANNELS_LAYERS и т. Д. Все были настроены.

Справочные ссылки:

  1. отправка сообщений группам в каналах django 2
  2. выпуск github
  3. каналы документов

РЕДАКТИРОВАТЬ: я мог отправить сообщение с помощью websocket-client отпредставление

from websocket import create_connection
ws = create_connection("ws://url")
ws.send("Hello, World")

Но возможно ли отправить без использования вышеуказанного (не хочу создавать соединение)?

Исходный код: chat-app

1 Ответ

0 голосов
/ 28 сентября 2018

благодарностей @Matthaus Woolard за ясную концепцию.

Так вот в чем проблема:

Клиент отключился, когда я попытался отправить сообщение от djangoПосмотреть.Это произошло, когда сервер перезапустился после изменения кода.Я обновил браузер, и он начал работать.

Глупая ошибка

Итак, подведем итог:

Добавьте следующее в connect ()в случае синхронного потребителя:

async_to_sync(self.channel_layer.group_add)('events', self.channel_name)

или добавьте этот случай Async Consumer:

await self.channel_layer.group_add('events', self.channel_name)

создайте представление следующим образом:

def alarm(request):
   layer = get_channel_layer()
   async_to_sync(layer.group_send)('events', {
           'type': 'events.alarm',
           'content': 'triggered'
        })
   return HttpResponse('<p>Done</p>')
...