断开连接后django通道无效状态错误

Posted

技术标签:

【中文标题】断开连接后django通道无效状态错误【英文标题】:django channels invalid state error after disconnnect 【发布时间】:2019-01-03 12:50:54 【问题描述】:

我使用 django-channels 来实现聊天消息框并通过 ajax 连接到 websocket,因为聊天框不占用全屏。 Im connecting to a particular socket when one user is selected and the messages are sending through the first time and its getting saved.When i close the chatbox im calling websocket close and disconnnect is executing,but when i close and reopen again im getting error

reconnecting-websocket.js:293 Uncaught INVALID_STATE_ERR : Pausing to 
reconnect websocket

当我打开聊天框时,也可以在其他频道中看到这些消息。在调用断开连接后,websocket 是否有可能保持连接并且频道不会被丢弃?

我的代码:

class ChatConsumer(AsyncConsumer):

    async def websocket_connect(self, event):
        print("connected", event)
        other_user = self.scope['url_route']['kwargs']['username']
    me = self.scope['user']

    thread_obj = await self.get_thread(me, other_user)
    self.thread_obj = thread_obj
    chat_room = "thread_".format(thread_obj.id)
    self.chat_room = chat_room
    await self.channel_layer.group_add(
         chat_room,
         self.channel_name
    )
    await self.send(
        "type": "websocket.accept"
    )

async def websocket_receive(self, event):

    print("MEssage received",event)
    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')
        me = self.scope['user']

        myResponse =
            'message': msg,
            'username': me.username
        
        if msg is not "":
            await self.create_chat_messages(me,msg)
        await self.channel_layer.group_send(
            self.chat_room,
            
                "type": "chat_message",
                "text":  json.dumps(myResponse)

            
        )
async def chat_message(self, event):
    await self.send(
        "type": "websocket.send",
        "text": event['text']
    )

async def websocket_disconnect(self):
    await self.channel_layer.group_discard(
        self.chat_room,
        self.channel_name
    )
    print("disconnected")

@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_messages(self,me,msg):
    thread_obj = self.thread_obj
    if msg is not "":
        print("MESSAGE",msg)
        print(thread_obj)
        print(me)
        chat_message = ChatMessage.objects.create(thread=thread_obj, user=me, message=msg)
        return chat_message
    else:
        return None

在我的脚本中:

$('.chatblob').click(function(e)
e.preventDefault();
$chatbox.removeClass('chatbox--empty');
var username = $(this).find('p:first').text();
console.log(username);
var loc = window.location;
var formData=$('#form');
var msgInput = $('#textmessage');
var wsStart = 'ws://';

if (loc.protocol == 'https:')
wsStart ='wss://';

var endpoint = wsStart + loc.host+"/messages/"+username+"/";
 console.log("endpoint: ",endpoint);
console.log("MESSAGE IS",msgInput.val());
 $.ajax(
      type: 'POST',
      url:'/messages/'+username+"/",
      data: 
      'username': username,
      'message': msgInput.val(),
       csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val()
       ,
       dataType: 'jsonp',
       jsonpCallback: "localJsonpCallback"

      );


   $.ajax(
      type: 'POST',
      url:"/student/get-thread/"+username,
      data: 
      'username': String(username),
       csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val()
       ,
      dataType:'json',
      success:function(e)
       console.log(e);
       console.log(e.success.queryset);
       $('.chatbox__body').empty();
       $('.chatbox__body').append(e.success.queryset);    
        ,
      error: function(e)
         console.log(e)
      
      );
     function localJsonpCallback(json) 
        if (!json.Error) 
           console.log("success");
        
        else 
            console.log("Error");
    
    
 var socket = new ReconnectingWebSocket(endpoint);
 chatHolder= $('.chatbox__body');
 var me = $('#myUsername').val();
 sockets.push(socket);
 socket.onmessage = function(e)
 var chatDataMsg=JSON.parse(e.data);
 console.log("chatmessage",chatDataMsg);
 chatHolder.append(chatDataMsg.message);

socket.onclose = function(e)
console.log("CLosing",e);

socket.onopen = function(e)
  console.log("open",e);
  formData.submit(function(event)
  event.preventDefault();
  var msgText = msgInput.val()
      var finalData = 
      'message' :msgText
   
  console.log(msgText);
  socket.send(JSON.stringify(finalData));
  console.log(JSON.stringify(finalData))
  console.log(endpoint);
  formData[0].reset();
 );


socket.onerror = function(e)
console.log("error",e);

socket.onclose = function(e)
console.log("Closers",e);

);
);

【问题讨论】:

【参考方案1】:

自从我使用 ajax 以来,使用重新连接 websocket 似乎一直存在问题。我改成普通的Websocket,现在可以正常使用了。

【讨论】:

以上是关于断开连接后django通道无效状态错误的主要内容,如果未能解决你的问题,请参考以下文章

通道 Websocket 立即与 ssl 断开连接

如果猜测错误,将用户与频道断开连接 DiscordPy

django 频道如何知道客户端已断开连接?

node.js http服务器,检测客户端何时断开连接

角度 SignalR 经常断开连接并显示错误状态代码 1006

判断socket断开连接的方法