Django Channels后端报错:进程关闭超时被终止
Here are the key issues in your code that are likely causing the shutdown timeout, along with corrected implementations:
1. Syntax Error in Connect Handler
Your teacher role block has an orphaned except statement with no corresponding try block. This invalid syntax causes runtime errors that disrupt proper connection lifecycle management.
2. Conflicting Disconnect Handlers
You’ve implemented both a synchronous disconnect method and an asynchronous websocket_disconnect method. For WebsocketConsumer (synchronous), only the disconnect method is needed—having both leads to duplicate cleanup logic and potential hangs.
3. Deprecated Channel Layer Method
group_discard is deprecated; use group_remove instead for removing a channel from a group.
4. Unhandled Exceptions in Disconnect
Database operations in disconnect lack error handling. If a Station or WorkClass doesn’t exist, uncaught exceptions will delay shutdown as the server processes the error.
Corrected WSConsumer Code
import json from channels.generic.websocket import WebsocketConsumer from asgiref.sync import async_to_sync from .models import WorkClass, Station class WSConsumer(WebsocketConsumer): def connect(self): self.room_name = self.scope["url_route"]["kwargs"]["room_name"] self.stid = self.scope["url_route"]["kwargs"]["stid"] self.types = self.scope["url_route"]["kwargs"]["types"] self.room_group_name = f"station_{self.room_name}" if self.types == "student": try: workclass = WorkClass.objects.get(workclass_id=self.room_name) st = Station.objects.get(id=self.stid) if st in workclass.stations.all(): st.state = True st.save() async_to_sync(self.channel_layer.group_add)( self.room_group_name, self.channel_name ) self.accept() else: self.disconnect(10) except (WorkClass.DoesNotExist, Station.DoesNotExist): self.disconnect(10) elif self.types == "teacher": try: # Optional: Verify workclass exists for teachers WorkClass.objects.get(workclass_id=self.room_name) async_to_sync(self.channel_layer.group_add)( self.room_group_name, self.channel_name ) self.accept() except WorkClass.DoesNotExist: raise StopConsumer() else: raise StopConsumer() def disconnect(self, close_code): # Remove channel from group async_to_sync(self.channel_layer.group_remove)( self.room_group_name, self.channel_name ) if self.types == "student": try: st = Station.objects.get(id=self.stid) st.state = False st.save() async_to_sync(self.channel_layer.group_send)( self.room_group_name, {"type": "list_stations", "message": self.room_name, "role": "stations"} ) except Station.DoesNotExist: # Skip if station doesn't exist to avoid delays pass def receive(self, text_data): text_data_json = json.loads(text_data) message = text_data_json["message"] role = text_data_json.get('roles', '') types = text_data_json.get('type', '') async_to_sync(self.channel_layer.group_send)( self.room_group_name, {"type": types, "message": message, "role": role} ) # Example group message handler def list_stations(self, event): message = event["message"] self.send(text_data=json.dumps({ "type": "list_stations", "message": message }))
Additional Server-Side Tweaks
If the issue persists after fixing code, adjust Daphne’s shutdown timeout:
- Start Daphne with the
--shutdown-timeoutflag to increase the allowed shutdown window (e.g.,daphne --shutdown-timeout 60 backend.asgi:application). - Ensure Redis is running smoothly and there are no connection delays between Channels and Redis.
内容的提问来源于stack exchange,提问作者Ammar Salahi

