我一直在尝试使用Django通道与一个房间进行简单的聊天。我要实现 @mention ,当聊天中的某人键入 @username 时,该用户应显示警报。
我添加了def chat_message
(在ChatConsumer
类中),检查消息是否具有模式(以'@'开头),然后从db中获得了一个用户提到并调用了发送消息的函数,但没有任何反应。请看下面的代码:
consumers.py
class ChatConsumer(AsyncWebsocketConsumer):
async def chat_message(self, event):
message = event['message']
username = event['username']
if re.match(r'(@[A-Za-z0-9]+)|([^0-9A-Za-z \t])', message) is not None:
mentions = re.findall(r'(@[A-Za-z0-9]+)', message)
for mention in mentions:
username = re.sub(r'@', '', mention)
user = await self.get_user(username)
await get_by_username(user, self.new_user, self.room_group_name)
# Send message to WebSocket
await self.send(text_data=json.dumps({
'message': message,
'username': username
}))
@database_sync_to_async
def get_user(self, username):
return User.objects.get(username=username)
在view.py中:
class ChannelView(View):
model = ChatMessage
template = 'chat/channel_2.html'
form = MessageForm
def get(self, request, channel_name):
form = self.form
users = [user.username for user in User.objects.all()]
return render(request, self.template, context={'channel_name': channel_name, 'form': form, 'users': users})
def post(self, request, channel_name):
bound_form = self.form(request.POST)
if bound_form.is_valid():
thread = channel_name
user = self.request.user
message = bound_form.cleaned_data.get("message")
ChatMessage.objects.create(user=user, thread=thread, message=message)
users = [user.username for user in User.objects.all()]
return render(request, self.template, context={'channel_name': channel_name, 'form': bound_form, 'users': users})
else:
return render(request, self.template, context={'channel_name': channel_name, 'form': bound_form, 'users': users})
async def get_by_username(mentioned_user, sender, group_name):
channel_layer = get_channel_layer()
message = 'You have a new message from {} in {} chat.'.format(sender, group_name)
await channel_layer.group_send(
'{}'.format(mentioned_user.id),
{
'type': 'chat_message',
'message': message
}
)
模板:
{% extends "base.html" %}
{% block content %}
<p class='lead'>Welcome {{ request.user.username }}!</p>
<div class="container">
<textarea id="chat-log" cols="60" rows="10"></textarea><br>
<textarea id="chat-message-input" type="text" cols="60" rows="1"></textarea><br>
<input id="chat-message-submit" type="button" value="Send">
{{ channel_name|json_script:"channel-name" }}
{{ users|json_script:'users' }}
</div>
<script>
const channelName = JSON.parse(document.getElementById('channel-name').textContent);
const user = JSON.parse(document.getElementById('users').textContent);
$('#chat-message-input').atwho({
at: "@",
data: user
});
const chatSocket = new WebSocket(
'ws://'
+ window.location.host
+ '/ws/'
+ channelName
+ '/'
);
console.log('ws = ', chatSocket)
chatSocket.onmessage = function(e) {
const data = JSON.parse(e.data);
document.querySelector('#chat-log').value += (data.username + ": " + data.message + '\n');
};
chatSocket.onclose = function(e) {
console.error('Chat socket closed unexpectedly');
};
document.querySelector('#chat-message-input').focus();
document.querySelector('#chat-message-input').onkeyup = function(e) {
if (e.keyCode === 13) {
document.querySelector('#chat-message-submit').click();
}
};
document.querySelector('#chat-message-submit').onclick = function(e) {
const messageInputDom = document.querySelector('#chat-message-input');
const message = messageInputDom.value;
chatSocket.send(JSON.stringify({
'message': message
}));
messageInputDom.value = '';
};
</script>
{% endblock %}