【问题标题】:Session variable value is not updated when websocket connection happens - Python当 websocket 连接发生时,会话变量值不会更新 - Python
【发布时间】:2021-05-27 04:00:44
【问题描述】:

我正在创建一个 API 来向回显服务器发送消息

为此,我使用来自此站点https://www.websocket.org/echo.html 的回声聊天服务器 URL ws://echo.websocket.org/。此连接将回显我们的输入。

当用户第一次请求 API 时,我需要与 echo server 建立连接并将用户消息发送到 echo server。当第二次用户请求相同的 API 时,这一次连接已经建立。所以,我只需要将用户消息发送到回显服务器。

为此,我使用 python 会话来存储连接详细信息。第一次建立连接时,我试图将其保存在会话中。 session['ConnetionMade'] = "True" 默认为假

所以,当用户第二次请求 API 时,这次 ConnetionMade 为 True。所以,我不会再建立联系了。

但是这里的会话变量在建立连接时不会更新。它总是错误的。但我们设置为 True。

以下是完整的工作代码。请帮我更新会话变量。

注意:当我们跳过套接字连接代码时,会话变量起作用

from flask import Flask
from flask import request, session
from config import config
import websocket

try:
    import thread
except ImportError:
    import _thread as thread


SECRET_KEY = 'a secret key'

app = Flask(__name__)
app.config.from_object(__name__)

@app.route('/')
def root():
    return 'Hello NLP....!'

userMessage = ""
@app.route('/whatsapp', methods=['POST'])
def echo():
    global userMessage
    userMessage = request.json['message']

    # session.clear()

    print("\n\nuserMessage: ", userMessage, "\n\n")

    print("ConnetionMade--: ", session.get('ConnetionMade', "False"))

    if session.get('ConnetionMade', "False") == "False":
        session['ConnetionMade'] = "True"
        print('True set to ConnetionMade ', session.get('ConnetionMade', "False"))
        echoConnection()
    else:
        session['ConnetionMade'] = "False"
        print('False set to ConnetionMade ', session.get('ConnetionMade', "False"))


    return ""


def echoConnection():

    if __name__ == "__main__":
        websocket.enableTrace(True)
        ws = websocket.WebSocketApp("ws://echo.websocket.org/",
                                  on_open = on_open,
                                  on_message = on_message,
                                  on_error = on_error,
                                  on_close = on_close)

        ws.run_forever()

    return ""

def on_message(ws, message):
    print("\n\nMessage received from Echo Socket server:", message, '\n\n')
    return

def on_error(ws, error):
    print("on_error ", error)
    return

def on_close(ws):
    print("on_close")
    return

def on_open(ws):
    def run(*args):

        print("\n\nSocket connection made. Now sending this message ("+userMessage+") to Echo Socket server\n\n")
        ws.send(userMessage)
        print("\nsent...\n")
        print("thread terminating...")

    thread.start_new_thread(run, ())

    return

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=config['server']['port'])

【问题讨论】:

  • 如果我理解正确的话,您希望每个访问您的 API 的用户都有一个唯一的 websocket-client 连接吗? websocket-client 库使用 websocket.create_connection 用于短期连接,websocket.WebSocketApp 用于长期运行循环。现在这个问题有些混乱,比如: 1. 你是如何点击这个 API 来验证会话是否工作的? 2. 为什么每次会话使用WebSocketApp 而不使用create_connection
  • 首先感谢您的回复。我在 Python 中只有 3 个月的 exp。所以,我可能错了,如果有的话,给我正确的解决方案。问题2回答:基本上我想实现实时聊天。所以我需要长时间运行的循环,所以只有我在使用 websocket.WebSocketApp。问题 1 回答:一旦用户第一次与代理连接,我想保存到会话。因此,下次用户键入时,我想检查是否使用保存的会话建立了连接,如果建立了连接,那么我不需要再次连接。我只需要使用现有连接发送消息。
  • 对于Basically I want to implement live chat.,我对您的问题的唯一困惑是,您正在使用python客户端连接到回显服务器(that hosted server just sends/replays your exact message),这意味着,在您的情况下,您是正在做:client agent --> your python code --> python client --> echo server。这不会帮助您构建聊天客户端。检查此以获取聊天应用程序的示例,该应用程序在您身边有需要实现的服务器:github.com/heroku-examples/python-websockets-chat
  • 我已经使用 WebSocket 实现了实时聊天。这里的问题是,当 WebSokcet 连接时,无法更新 Flash 会话数据。如果 WebSocket 没有连接,那么那个时候 Flash 会话可以正常工作。
  • 我无法在此处分享我的实时代理端点网址。因此,我使用 echo bot 构建了一些示例,并在此处给出了该代码。

标签: python websocket socket.io client


【解决方案1】:

在您的情况下,ws.run_forever() 会阻塞线程,然后不会捕获对 API 的进一步调用。

您可以在守护线程中运行 websocket,并确保使用其send 方法与 websocket 服务器通信。

类似这样的:

from flask import Flask
from flask import request, session
import websocket
import threading

SECRET_KEY = 'a secret key'

app = Flask(__name__)
app.config.from_object(__name__)

websocket_client = None

@app.route('/')
def root():
    return 'Hello NLP....!'

@app.route('/whatsapp', methods=['POST'])
def echo():
    userMessage = request.json['message']

    # session.clear()
    print("userMessage: ", userMessage, "\n")
    print("ConnetionMade--: ", session.get('ConnetionMade', "False"))

    if session.get('ConnetionMade', "False") == "False":
        session['ConnetionMade'] = "True"
        print('True set to ConnetionMade ', session.get('ConnetionMade', "False"))
        send_message_to_websocket_server(userMessage)

    return ""

def send_message_to_websocket_server(message):
    print("Sending message to WebSocket Server")
    websocket_client.send(message)

def createConnection():
    ws = websocket.WebSocketApp("ws://echo.websocket.org/",
                              on_open = on_open,
                              on_message = on_message,
                              on_error = on_error,
                              on_close = on_close)

    # Initialise the run_forever inside a thread and make this thread as a daemon thread
    wst = threading.Thread(target=ws.run_forever)
    wst.daemon = True
    wst.start()
    return ws

def on_message(ws, message):
    print("Message received from Echo Socket server:", message)

def on_error(ws, error):
    print("on_error ", error)

def on_close(ws):
    print("on_close")

def on_open(ws):
    print("Socket connection opened")

if __name__ == "__main__":
    websocket_client = createConnection()
    app.run(host='0.0.0.0', port=8001)  # I have hardcoded the port to test this

现在,如果我考虑到会话并使用以下命令点击它,则使用 Curl,如果会话是新的,它只会向 websocket 服务器发送回显:

curl -s -i -X POST http://0.0.0.0:8001/whatsapp\
   -d '{"message":"Sample"}' -H "Content-Type: application/json"\
   --cookie cookie.txt --cookie-jar cookie.txt

它将始终获取最新消息并将其回显到控制台。

【讨论】:

  • 非常感谢。我根据您的解决方案更新了我的代码。现在运行良好?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-23
  • 2016-05-11
相关资源
最近更新 更多