鱼C论坛

 找回密码
 立即注册
查看: 2239|回复: 4

[已解决]求助Python Websocket+Django

[复制链接]
发表于 2023-4-20 15:34:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
按照各种教程的 setting routings类都配置完成 但是无法建立连接。后台报错Not found,网页里直接显示WebSocket connection to 'ws://127.0.0.1:8000/ws/wscon' failed:
对没错,他甚至不告诉我错误信息。
最佳答案
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名称。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 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())
]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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>替换为包含您的路由文件的应用名称。

如果您在尝试这些更改后仍然遇到问题,请提供更多详细信息,以便我们能够进一步帮助您解决问题。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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名称。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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等方法都是对集合本身进行修改,不会创建新的集合。如果需要创建新的集合并保留原有集合,可以使用集合的拷贝或使用新的变量来存储结果。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-23 15:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表