2016-09-04 8 views
8

나는이 문서를 읽고 예제를 가지고 놀면서 django-channels을 시도해 보았습니다.django 채널을 사용하여 단일 사용자에게 메시지 보내기

데이터베이스에 새 인스턴스를 저장하여 트리거되는 단일 사용자에게 메시지를 보내고 싶습니다.

유스 케이스를 사용하여 새 알림을 만들고 (알림을 저장하면)이 알림을 단일 사용자에게 보냅니다.

가합니다 (django-channels docs에서)

수있는 것처럼 이것은 중요한 부분은 당신이 코드를 실행 (그래서 채널 전송) 어떤 이벤트에 응답 할 수 있다는 것입니다 ... 소리 - 그것은 포함 당신은 을 만듭니다. 모델 저장, 다른 수신 메시지 또는 뷰 및 양식 내부의 코드 경로에서 을 트리거 할 수 있습니다.

문서를 더 읽고 django-channels examples으로 놀아 보았지만 어떻게 할 수 있는지 알 수 없습니다. 데이터 바인딩 및 라이브 블로그 예제는 그룹에 전송하는 방법을 보여 주지만 단일 사용자에게 보내는 방법은 알 수 없습니다.

모든 의견을 많이 주시면 감사하겠습니다.

답변

10

입니다. 당신의 ws_connect 기능에 파이썬 기능에서

당신은 단지 그들을 위해 AA 그룹에 해당 사용자를 추가 할 수 있습니다

consumers.py

from channels.auth import channel_session_user_from_http, 
from channels import Group 

@channel_session_user_from_http 
def ws_connect(message): 
    Group("%s" % <user>).add(message.reply_channel) 

파이썬 코드에서 해당 사용자에게 메시지를 보내려면 :

내 view.py

import json 
from channels import Group 

def foo(user): 
    Group("%s" % <user>).send({ 
     "text": json.dumps({ 
      "foo": 'bar' 
     }) 
    }) 

연결되어 있으면 메시지를 받게됩니다. 사용자가 websocket에 연결되어 있지 않으면 자동으로 실패합니다.

각 사용자의 그룹에만 하나의 사용자 만 연결해야합니다. 그렇지 않으면 여러 사용자가 특정 사용자 만의 메시지를받을 수 있습니다.

django 채널 예제, 특히 라우팅 구현 방법, 클라이언트 측에서 websocket 연결 생성 및 django_channels 설정에 대해서는 multichat을보십시오.

django channels docs도 확인하십시오.우리가 등록

그냥 @luke_aus 답변처럼 :

+1

의도 된 방법일까요, 아니면 해결 방법일까요? – Shubham

+0

그룹이 없으면 소비자가 아닌 다른 사람이 그것을 할 수 없습니다. message.reply_chanel을 얻으려면 소비자 내에 있어야합니다. 소비자 이외에 사용자를 액세스하려면 그룹을 만들어야합니다. https://channels.readthedocs.io/en/stable/concepts.html#channel-types에서 관련 문서를 확인하십시오. 또한 여기에 제공된 Multichat 및 Livebloe 예제를 모두 확인하십시오. https://github.com/andrewgodwin/channels-examples –

+0

에 동일한 질문이있었습니다. 그것을위한 그룹 만들기는 의도가 아닙니다. 다른 옵션이 없다고 생각합니다. –

2

가장 좋은 방법은 특정 사용자에 대한 그룹을 만드는 것입니다. 당신이 Group("%s" % <user>).add(message.reply_channel)

주에 해당 사용자를 추가 할 수 있습니다 ws_connect 때 : 내 웹 소켓의 URL이 특정 사용자에 대한 그룹을 만드는 @ 플립의 대답에 확장 ws://127.0.0.1:8000/<user>

+0

감사합니다. 그렇다면 사용 케이스별로 사용자 당 하나의 그룹을 만들겠습니까? –

+0

@luke_aus 예 ... 대부분의 경우에 작동합니다 ... –

+0

감사합니다. 어떤 아이디어가 얼마나 잘 확장 될 것인가? –

0

그냥 당신이 ResourceBindings 작업하는 경우, 당신은 또한 그렇게 만 사용자가 "소유"라는 객체가이 업데이트를 검색 할 수 있습니다, @의 luke_aus의 답변을 확장하는 해당 사용자 만 볼 수 있어야 우리가 작업을 게시 할 수 있습니다 그것의 자신의 그룹에 사용자 (update, create) 등 :

from channels.auth import channel_session_user_from_http, 
from channels import Group 

@channel_session_user_from_http 
def ws_connect(message): 
    Group("user-%s" % message.user).add(message.reply_channel) 

이제 우리는 해당 바인딩을 변경할 수 있습니다 바인딩 된 객체가 속한 경우에만 변경을 발행 있도록 해당 사용자에게 다음과 같은 모델을 가정합니다.

class SomeUserOwnedObject(models.Model): 
    owner = models.ForeignKey(User) 

이제 우리는이 하나의 사용자에 게시 될 것입니다 우리의 사용자 그룹이 모델과 모든 작업 (갱신, 생성 등)를 결합 할 수있다 : 그것에 대해

class SomeUserOwnedObjectBinding(ResourceBinding): 
    # your binding might look like this: 
    model = SomeUserOwnedObject 
    stream = 'someuserownedobject' 
    serializer_class = SomeUserOwnedObjectSerializer 
    queryset = SomeUserOwnedObject.objects.all() 

    # here's the magic to only publish to this user's group 
    @classmethod 
    def group_names(cls, instance, action): 
     # note that this will also override all other model bindings 
     # like `someuserownedobject-update` `someuserownedobject-create` etc 
     return ['user-%s' % instance.owner.pk] 
관련 문제