我正在尝试在Django Channels应用程序中完成通知系统。
当我通过网络套接字发送消息或文本字符串时,websocket.recieve
将在发送初始消息后生成大量空字符串。
127.0.0.1:54917 - - [27/Apr/2019:19:04:05] "WSCONNECTING /messages/trilla" - -
connected {'type': 'websocket.connect'}
127.0.0.1:54917 - - [27/Apr/2019:19:04:05] "WSCONNECT /messages/trilla" - -
receive {'type': 'websocket.receive', 'text': '{"message":"hi there"}'}
websocket.receive
receive {'type': 'websocket.receive', 'text': '{"message":""}'}
websocket.receive
receive {'type': 'websocket.receive', 'text': '{"message":""}'}
websocket.receive
receive {'type': 'websocket.receive', 'text': '{"message":""}'}
websocket.receive
导航栏具有一个JS脚本,用于添加新的通知。根据服务器消息构造html字符串,然后将其插入html页面。
单击导航栏通知图标时,我得到NOT NULL constraint failed: chat_chatmessage.message
。我假设由于空字符串问题而产生大量空消息。
这是我单击通知图标时的日志
receive {'type': 'websocket.receive', 'text': '{"type":"notification_read","username":{},"notification_id":{"jQuery33100053785670652706231":{"display":""}}}'}
websocket.receive
2019-04-28 11:59:47,041 ERROR Exception inside application: NOT NULL constraint failed: chat_chatmessage.message
很明显,数据没有正确传递。我遵循了有关Django Channels部分的教程,并且在尝试执行此操作之前没有使用JS / WebSockets的经验,所以我在查找有问题的代码方面的能力有限。
consumers.py
async def websocket_receive(self, event):
# when a message is recieved from the websocket
print("receive", event)
message_type = event.get('type', None) #check message type, act accordingly
print(message_type)
if message_type == "notification_read":
# Update the notification read status flag in Notification model.
notification = Notification.object.get(id=notification_id)
notification.notification_read = True
notification.save() #commit to DB
print("notification read")
front_text = event.get('text', None)
if front_text is not None:
loaded_dict_data = json.loads(front_text)
msg = loaded_dict_data.get('message')
user = self.scope['user']
username = 'default'
notification_id = 'default'
if user.is_authenticated:
username = user.username
myResponse = {
'message': msg,
'username': username,
'notification': notification_id,
}
await self.create_chat_message(user, msg)
# broadcasts the message event to be sent, the group send layer
# triggers the chat_message function for all of the group (chat_room)
await self.channel_layer.group_send(
self.chat_room,
{
'type': 'chat_message',
'text': json.dumps(myResponse)
}
)
# chat_method is a custom method name that we made
async def chat_message(self, event):
# sends the actual message
await self.send({
'type': 'websocket.send',
'text': event['text']
})
async def websocket_disconnect(self, event):
# when the socket disconnects
print('disconnected', event)
@database_sync_to_async
def get_thread(self, user, other_username):
return Thread.objects.get_or_new(user, other_username)[0]
@database_sync_to_async
def create_chat_message(self, me, msg):
thread_obj = self.thread_obj
return ChatMessage.objects.create(thread=thread_obj, user=me, message=msg)
base.html
<script>
$(document).ready(function() {
$("#notificationLink").click(function() {
var data = {
"type": "notification_read",
"username": username,
"notification_id": notification_id,
}
socket.send(JSON.stringify(data));
$("#notificationContainer").fadeToggle(300);
$("#notification_id").fadeOut("slow");
return false;
});
</script>
<script>
// websocket scripts - client side*
var loc = window.location
var formData = $("#form")
var msgInput = $("#id_message")
var chatHolder = $('#chat-items')
var me = $('#myUsername').val()
var notification = $("#notificationLink")
var wsStart = 'ws://'
if (loc.protocol == 'https:') {
wsStart = 'wss://'
}
var endpoint = wsStart + loc.host + loc.pathname
var socket = new ReconnectingWebSocket(endpoint)
// below is the message I am receiving
socket.onmessage = function(e) {
var data = JSON.parse(event.data);
// Find the notification icon/button/whatever and show a red dot, add the notification_id to element as id or data attribute.
notification.append("<span id=#notification_id>" + notification.notification_id)
console.log("message", e)
var chatDataMsg = JSON.parse(e.data)
chatHolder.append('<li>' + chatDataMsg.message + ' from ' + chatDataMsg.username + '</li>')
}
// below is the message I am sending
socket.onopen = function(e) {
console.log("open", e)
formData.submit(function(event) {
event.preventDefault()
var msgText = msgInput.val()
var finalData = {
'message': msgText
}
socket.send(JSON.stringify(finalData))
formData[0].reset()
})
}
导航栏
<li id="notification_li" class="nav-item">
<a class="nav-link" href="#" id="notificationLink">
<i class="fas fa-envelope"></i> Inbox</a>
{% for notifications in notification %}
<span id="notification_id{{notification_id}}">{{ notifications.notification_chat }}</span>
{% endfor %}
<div id="notificationContainer">
<div id="notificationTitle">Notifications</div>
<div id="notificationsBody" class="notifications">
{% for notifications in notification %}
<a href="{% url 'chat:thread' user %}">
<span id="notification-{{notification.id}}">
{{ notifications.notification_chat.message }}
via {{ notifications.notification_chat.user }}
at {{ notifications.notification_chat.thread.timestamp }}
</span>
</a>
...
答案 0 :(得分:0)
问题应该出在您的模型文件中。 NOT NULL
约束设置在一个字段上,当您尝试将其创建为空时会引发错误。因此,要超越此限制,您需要设置null=True
。
例如:
date_of_birth = models.DateField(blank=True, null=True)
尝试查看create_chat_message
函数中使用的模型。
答案 1 :(得分:0)
在发送通知时,您无需阅读所有剩余代码,因此可以简单地添加return
if message_type == "notification_read":
# Update the notification read status flag in Notification model.
notification = Notification.object.get(id=notification_id)
notification.notification_read = True
notification.save() #commit to DB
print("notification read")
return