Не может отправлять сокетные сообщения вне Consumer в представлениях Django или где-то еще
из показанного заголовка следует, что я не могу отправлять сообщения сокета, вот мой код
class ChatConsumer(JsonWebsocketConsumer):
_user = None
@property
def cu_user(self):
try:
self.user = self.scope['user']
self._user = User.objects.get(id=self.user.id)
except User.DoesNotExist as e:
print(e)
return self._user
def connect(self):
# Join users group
async_to_sync(self.channel_layer.group_add)(
'users',
self.channel_name
)
self.accept()
def disconnect(self, close_code):
# Leave app
async_to_sync(self.channel_layer.group_discard)(
'users',
self.channel_name
)
self.close()
# Receive json message from WebSocket
def receive_json(self, content, **kwargs):
if content.get('command') == 'chat_handshake':
self._handshake(content)
elif content.get('command') == 'user_handshake':
self.user_handshake()
def _handshake(self, data):
"""
Called by receive_json when someone sent a join command.
"""
logger.info("ChatConsumer: join_chat: %s" % str(data.get('chat_id')))
try:
chat = "%s_%s" % (data.get('chat_type'), data.get('chat_id'))
except ClientError as e:
return self.handle_client_error(e)
# Add them to the group so they get room messages
self.channel_layer.group_add(
chat,
self.channel_name,
)
# Instruct their client to finish opening the room
self.send_json({
'command': 'chat_handshake',
'chat_id': str(data.get('chat_id')),
'user': str(self.cu_user),
})
# Notify the group that someone joined
self.channel_layer.group_send(
chat,
{
"command": "chat_handshake",
"user": self.cu_user,
}
)
def user_handshake(self):
key = f'user_{self.cu_user.id}'
self.channel_layer.group_add(
key,
self.channel_name
)
self.send_json({
'command': 'user_handshake',
'user': str(self.cu_user)
})
self.channel_layer.group_send(
key,
{
'command': 'user_handshake',
'user': str(self.cu_user)
}
)
# this is not working
def send_socket(self, event):
logger.info(event)
print(event)
self.send(text_data=json.dumps(event['message']))
Я написал свой код вне потребителя таким образом
def send_to_socket(broadcast, keys=None):
if keys:
if not isinstance(keys, (list, tuple)):
keys = [keys]
sent_keys = [] # include group names
for key in keys:
if not key in sent_keys:
sent_keys.append(key)
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
key,
{
'type': 'send.socket',
'message': broadcast
}
)
Я пытаюсь отправлять сообщения из views.py с помощью следующего кода
@action(detail=False, methods=['GET'], url_name='socket_message')
def socket_message(self, request, *args, **kwargs):
key = ['user_1']
broadcast = {
'type': 'test_socket_message',
'message': 'i am here',
'user_id': 1
}
send_to_socket(broadcast, key)
return Response({"status": "OK"})
Надеюсь, из кода все понятно. Я пробовал много раз, но не смог отправить сообщение. Любая помощь будет признательна, так как я новичок в каналах
Поскольку я использую JsonWebsocketConsumer. Я допустил глупую ошибку, но это был большой опыт для меня. Но в любом случае я хочу опубликовать, как я смог решить эту проблему, поскольку другие могут использовать ее
во-первых я должен был написать свое user_hanshake вот так
def user_handshake(self):
key = f'user_{self.cu_user.id}'
# this was changed
async_to_sync(self.channel_layer.group_add)(
key,
self.channel_name
)
self.send_json({
'command': 'user_handshake',
'user': str(self.cu_user)
})
в размещенном коде было написано self.channel_layer.group_add без async_to_sync это было причиной того, что пользователь не был добавлен в группы, поэтому мое сообщение не было получено. После этого все работает гладко. Спасибо