沙包毛玉 发表于 2023-4-20 15:34:13

求助Python Websocket+Django

按照各种教程的 setting routings类都配置完成 但是无法建立连接。后台报错Not found,网页里直接显示WebSocket connection to 'ws://127.0.0.1:8000/ws/wscon' failed:
对没错,他甚至不告诉我错误信息。

沙包毛玉 发表于 2023-4-20 15:37:40

以下是代码:
class ChatConsumer(WebsocketConsumer):

    # 客户端向服务器请求建立连接
    def websocket_connect(self, message):
      """
      有客户端向后台发送websocket连接请求时自动触发,服务器允许和客户端创建连接
      """
      print("连接已建立")
      self.accept()

    # 发送消息
    def websocket_receive(self, message):
      """
      浏览器基于websocket向后端发送数据,自动触发接收消息
      """
      self.send("不要回复不要回复")
      # 服务端主动断开连接
      # self.close()

    # 断开连接
    def websocket_disconnect(self, message):
      """
      客户端与服务器断开连接时,自动触发
      """
      print("断开连接")
      raise StopConsumer

application = ProtocolTypeRouter({
    'http': get_asgi_application(),# 如果是http的请求就走这条
    'websocket': URLRouter(routings.websocket_urlpatterns),# 如果是websocket就走这一条
})

# 创建路由所用文件
websocket_urlpatterns = [
    # 正则表达式创造websocket接口
    re_path(r'ws/(?P<websocket>\w+)/$', chat_consumer.ChatConsumer.as_asgi())
]

isdkz 发表于 2023-4-20 15:43:26

根据您提供的代码,问题可能出现在websocket_urlpatterns中的正则表达式。尝试更新您的路由文件中的正则表达式,如下所示:
websocket_urlpatterns = [
    # 正则表达式创造websocket接口
    re_path(r'ws/wscon/$', chat_consumer.ChatConsumer.as_asgi())
]

这将确保您的WebSocket连接请求能够匹配正确的URL模式。

此外,确保您的Django项目的settings.py文件中已经添加了channels和相关的配置。这里是一个基本的示例配置:

INSTALLED_APPS = [
    # ...
    'channels',
]

# 设置Django默认的HTTP后端
ASGI_APPLICATION = '<your_project_name>.asgi.application'

# 设置channels配置
CHANNEL_LAYERS = {
    'default': {
      'BACKEND': 'channels.layers.InMemoryChannelLayer',
    },
}


确保您的Django项目根目录下有一个名为asgi.py的文件,它应该包含与您提供的相似的内容:

import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
import <your_app_name>.routings as routings
from channels.auth import AuthMiddlewareStack

os.environ.setdefault('DJANGO_SETTINGS_MODULE', '<your_project_name>.settings')

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AuthMiddlewareStack(
      URLRouter(
            routings.websocket_urlpatterns
      )
    ),
})


确保将<your_project_name>替换为您的Django项目名称,将<your_app_name>替换为包含您的路由文件的应用名称。

如果您在尝试这些更改后仍然遇到问题,请提供更多详细信息,以便我们能够进一步帮助您解决问题。

陶远航 发表于 2023-4-22 10:17:36

根据您提供的代码和错误信息,可以看到Websocket连接请求的URL为ws://127.0.0.1:8000/ws/wscon。根据您提供的路由配置代码,Websocket连接请求应该匹配到URL为ws/(?P<websocket>\w+)/$的路由,并将请求的参数作为websocket传递给ChatConsumer类。

但是,您在路由配置代码中没有指定websocket参数的名称,导致chat_consumer.ChatConsumer.as_asgi()方法中无法解析该参数,因此出现了404 Not found错误。

为了解决这个问题,您需要将路由配置代码中的正则表达式修改为ws/(?P<websocket_name>\w+)/$,然后将websocket_name作为参数传递给ChatConsumer类。修改后的代码如下:
websocket_urlpatterns = [
    # 正则表达式创造websocket接口
    re_path(r'ws/(?P<websocket_name>\w+)/$', chat_consumer.ChatConsumer.as_asgi())
]
然后,在ChatConsumer类中,您需要将websocket_name参数传递给WebsocketConsumer的构造函数。修改后的代码如下:
class ChatConsumer(WebsocketConsumer):
    def __init__(self, *args, **kwargs):
      super().__init__(*args, **kwargs)
      self.websocket_name = self.scope['url_route']['kwargs']['websocket_name']

    def websocket_connect(self, message):
      print(f"连接已建立:{self.websocket_name}")
      self.accept()

    def websocket_receive(self, message):
      self.send("不要回复不要回复")

    def websocket_disconnect(self, message):
      print(f"断开连接:{self.websocket_name}")
      raise StopConsumer
请注意,修改后的代码将websocket_name参数从URL中提取出来,并将其存储为ChatConsumer对象的一个属性。在websocket_connect和websocket_disconnect方法中,我们使用该属性来显示连接建立和断开的Websocket名称。

zhuoyue65 发表于 2023-4-22 14:21:22

在Python中,set对象有很多方法来对其进行修改,其中包括update和symmetric_difference_update方法。

update方法会将一个集合中的元素添加到当前集合中,相当于对当前集合进行并集操作。
symmetric_difference_update方法会将当前集合和另一个集合的不重复元素合并,并更新当前集合。
在你提供的代码中,使用s.symmetric_difference_update('python')和s.symmetric_difference("Python")都是将s和字符串'python'或"Python"取对称差集。但是,这两个方法的区别在于是否更新当前集合。

s.symmetric_difference_update('python')会将s和字符串'python'取对称差集,并将结果更新到s中。
s.symmetric_difference("Python")会将s和字符串'Python'取对称差集,但不会更新s,而是返回一个新的集合作为结果。
因此,使用symmetric_difference_update方法会更新s,所以最终s的值为{'o', 't', 'f', 'i', 'n', 'y', 'p', 'h', 'c', 's'}。而使用s.symmetric_difference("Python")只是返回一个新的集合,不会修改s本身,所以s的值不变,仍然为{'f', 'i', 's', 'h', 'c'}。

需要注意的是,update和symmetric_difference_update等方法都是对集合本身进行修改,不会创建新的集合。如果需要创建新的集合并保留原有集合,可以使用集合的拷贝或使用新的变量来存储结果。
页: [1]
查看完整版本: 求助Python Websocket+Django