【问题标题】:Link Django-cookie sessionId to Channels 2.02 connection?将 Django-cookie sessionId 链接到 Channels 2.02 连接?
【发布时间】:2018-02-27 16:15:21
【问题描述】:

感谢大家阅读我的第一篇文章。使用 Django 2.02,Django-channels 2.02。

我希望将从前端发送到后端的信息存储到 Django 会话存储中。我的问题是,只要 WebSocket 打开,Django-channels 会话范围似乎只存储信息,但我需要它像 Django http-session 一样存储它。

前端 index.html 中的第一个 javascript。

<script>
const conn = new WebSocket('ws://localhost:8000/');

var msg = {
    type: "message",
    message: "Trying to find a solution",
    date: Date.now(),
};

msg = JSON.stringify(msg);
conn.onopen = () => conn.send(msg);
</script> 

Consumers.py

from channels.generic.websocket import JsonWebsocketConsumer
from importlib import import_module
from django.conf import settings
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
#Have tried SessionStore to store but will also not work

class ConnectConsumer(JsonWebsocketConsumer):
    def connect(self):
        self.accept()

    def receive(self, text_data=None):
        text = self.decode_json(text_data) #decode incoming JSON
        text_message = text.get('message') 

        print(self.scope["session"]["message"]) #prints "None"
        self.scope["session"]["message"] = text_message
        self.scope['session'].save()
        print(self.scope["session"]["message"]) #prints "Trying to find a solution"

    def disconnect(self, message):
        pass

路由.py

from django.urls import path
from channels.http import AsgiHandler
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from consumers import ConnectConsumer

application = ProtocolTypeRouter({
    "websocket": AuthMiddlewareStack(
        URLRouter([
            path("/", ConnectConsumer),
        ]),
    )
})

Views.py

from django.shortcuts import render

def index(request):
    print(request.session.keys()) #returns Empty dict([])
    return render(
        request,
        'index.html',
    )

请告诉我这个问题是否过于宽泛或我缺少相关信息。

【问题讨论】:

    标签: django session websocket django-channels anonymous-users


    【解决方案1】:

    尝试将您的views.py 代码更改为

    from django.shortcuts import render
    
    def index(request):
        if not 'message' in request.session.keys():
            request.session['message'] = ''
            print("'message' key created in HTTP session")    
        print(request.session['message']) # it should print "" on the first run
                                          # and "Trying to find a solution" after that
        return render(
            request,
            'index.html',
        )
    

    我不太确定导致此问题的原因,但我想这与SessionMiddleware 的工作方式有关。似乎SessionStore.save() 方法在consumers.py 内部调用时不会保存新的会话密钥。这就是我在views.py 中预先分配“消息”键的原因。


    编辑 1 - 我的consumers.py

    from channels.generic.websocket import JsonWebsocketConsumer
    #from importlib import import_module
    from django.conf import settings
    #SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
    #Have tried SessionStore to store but will also not work
    
    class ConnectConsumer(JsonWebsocketConsumer):
        def connect(self):
            self.accept()
    
        def receive(self, text_data=None):
            text = self.decode_json(text_data) #decode incoming JSON
            text_message = text.get('message') 
    
            print(self.scope["session"]["message"]) 
            self.scope["session"]["message"] = text_message
            self.scope['session'].save()
            print(self.scope["session"]["message"]) #prints "Trying to find a solution"
    
        def disconnect(self, message):
            pass
    

    【讨论】:

    • 感谢 bjbschmitt 的回答。我试过了,但是 views.py 和 consumer.py(SessionStore) 将信息存储在不同的 session_keys 中。你能发布一个你的consumers.py看起来如何的例子吗?
    • 我使用了和你一样的consumers.py。但无论如何我都会将它添加到我的答案中。顺便说一句,你能给我看看你的settings.py 文件吗?也许这与您的会话设置有关。
    • 现在可以完美运行了!对不起,是我的错。我尝试了不同的解决方案,所以当我尝试这个时,我将它与另一种解决方案混合在一起。我很高兴。
    【解决方案2】:

    我知道这个线程有点老了,但是我花了一整天的时间来弄清楚为什么没有通过 websocket 连接发送 cookie,因此我无法访问消费者中的正确会话。 原来我只需要更换

    new WebSocket('ws://localhost:8000/');
    

    new WebSocket('ws://127.0.0.1:8000/');
    

    除此之外,首先将会话或新会话密钥保存在消费者之外(例如在视图中)确实很重要,如@bjbschmitt 答案所示。

    我希望这会为某人节省很多时间。

    【讨论】:

      猜你喜欢
      • 2022-01-12
      • 2019-05-03
      • 1970-01-01
      • 2019-06-22
      • 1970-01-01
      • 2021-07-03
      • 2023-03-20
      • 2021-11-09
      • 1970-01-01
      相关资源
      最近更新 更多