如何在烧瓶中获得连接的客户端

编程入门 行业动态 更新时间:2024-10-13 00:30:46
本文介绍了如何在烧瓶中获得连接的客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我需要在我的flask应用程序上显示已连接客户端的总数,我编写此代码来检查已连接和已断开的连接.

hi i need to display total number of connected clients on my flask app i write this code for checking connected and disconnected connections.

app = Flask(__name__) socketio = SocketIO(app) clients = [] @socketio.on('connect', namespace='/') def connect(): clients.append(request.namespace) @socketio.on('disconnect', namespace='/') def disconnect(): clients.remove(request.namespace)

然后我渲染这样的模板

return render_template_string(TABLE_TEMPLATE, data=data, clients=len(clients))

在html部分中,我这样称呼

In html part i call like this

<h1>{{ clients }} </h1>

但是在网页上,即使客户端已连接,它仍会显示0,我从客户端获得输出并且已连接,应该打印1 2取决于连接的客户端数.即使我打印此打印(len(clients)),它也会返回0.甚至我的客户端都已连接,我得到了输出.

but on webpage it keep showing 0 even client is connect i get output from client and it is connected it should print 1 2 depends how many clients are connected. even if i print this print(len(clients)) it return 0. even my client is connect and i get output.

这是我更新的代码

from flask import Flask, request, render_template_string from flask_socketio import SocketIO, emit app = Flask(__name__) socketio = SocketIO(app, logge=True) clients = 0 @socketio.on("connect", namespace="/") def connect(): # global variable as it needs to be shared global clients clients += 1 # emits a message with the user count anytime someone connects emit("users", {"user_count": clients}, broadcast=True) @socketio.on("disconnect", namespace="/") def disconnect(): global clients clients -= 1 emit("users", {"user_count": clients}, broadcast=True) TABLE_TEMPLATE = """ <script src="cdnjs.cloudflare/ajax/libs/socket.io/1.7.3/socket.io.min.js"></script> <script src="ajax.googleapis/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> $(document).ready(function(){ var namespace = '/'; var socket = io.connect('' + document.domain + ':' + location.port + namespace); // Update the counter when a new user connects socket.on('users', function(users) { userCount = document.getElementById('user_counter'); userCount.innerHTML = users.user_count; }); }); </script> <h1 id='user_counter'></h1> <style> table, th, td { border: 1px solid black; } </style> <table style="width: 100%"> <thead> <th>Client</th> <th>IP</th> <th>Status</th> </thead> <tbody> {% for row in data %} <tr> <td><center>{{ row.client }}</td></center> <td><center>{{ row.ip }}</td></center> <td><center>{{ row.status }}</td></center> </tr> {% endfor %} </tbody> </table> """ @app.route("/device_add", methods=['POST']) def device_add(): name = request.args.get('name') with open('logs.log', 'a') as f: f.write(f'{name} Connected USB from IP: {request.remote_addr} \n') return 'ok' @app.route("/device_remove", methods=['POST']) def device_remove(): name = request.args.get('name') with open('logs.log', 'a') as f: f.write(f'{name} Disconnected USB from IP: {request.remote_addr}\n') return 'ok' @app.route("/", methods=['GET']) def device_list(): keys = ['client', 'ip', 'status'] data = [] with open('logs.log', 'r') as f: for line in f: row = line.split() data.append(dict(zip(keys, [row[0], row[-1], row[1]]))) return render_template_string(TABLE_TEMPLATE, data=data) if __name__ == "__main__": socketio.run(app)

客户端:

import requests import subprocess, string, time import os url = '127.0.0.1:5000/' name = os.uname()[1] def on_device_add(): requests.post(f'{url}/device_add?name={name}') def on_device_remove(): requests.post(f'{url}/device_remove?name={name}') def detect_device(previous): total = subprocess.run('lsblk | grep disk | wc -l', shell=True, stdout=subprocess.PIPE).stdout time.sleep(3) # if condition if new device add if total > previous: on_device_add() # if no new device add or remove elif total == previous: detect_device(previous) # if device remove else: on_device_remove() # Infinite loop to keep client running. while True: detect_device(subprocess.run(' lsblk | grep disk | wc -l', shell=True , stdout=subprocess.PIPE).stdout)

推荐答案

阅读了 socket.io 后,文档,我已经设法在您的代码中发现了问题.

After reading a bit of socket.io documentation I've managed to spot the problems in your code.

暂时不是问题,但是对于此用例而言,递增/递减int计数器绰绰有余.其次,您不必将该计数器传递给render_template调用,因为您基本上是在conenct事件有机会触发之前传递用户计数的.您应该发出一条消息(在本示例中为users主题),该消息将通知您的页面某些更改:

Not a problem per-se, but incrementing/decrementing an int counter is more than enough for this use case. Secondly, you don't have to pass that counter to the render_template call as you're basically passing the user count before the conenct event has had the opportunity to fire. You should emit a message (in this example with a users topic) that will inform your page that something has changed:

from flask import Flask, request, render_template_string from flask_socketio import SocketIO, emit app = Flask(__name__) socketio = SocketIO(app, logge=True) clients = 0 @socketio.on("connect", namespace="/") def connect(): # global variable as it needs to be shared global clients clients += 1 # emits a message with the user count anytime someone connects emit("users", {"user_count": clients}, broadcast=True) @socketio.on("disconnect", namespace="/") def disconnect(): global clients clients -= 1 emit("users", {"user_count": clients}, broadcast=True)

此外,您没有在模板中打开与套接字的连接,这使您可以侦听socketio装饰器发出的消息并更新所有连接的客户端.您还需要编写一些JavaScript,以指定用户每次连接/断开连接时都需要更新计数器.

Moreover, you didn't open a connection to the socket in your template, this allows you to listen to the messages emitted by your socketio decorators and update all connected clients. You will also need to write a bit of javascript to specify that the counter needs to be updated anytime a user connects/disconnects.

<!-- Remember to import socketio library --> <script src="cdnjs.cloudflare/ajax/libs/socket.io/1.7.3/socket.io.min.js"></script> <script src="ajax.googleapis/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> $(document).ready(function(){ var namespace = '/'; var socket = io.connect('' + document.domain + ':' + location.port + namespace); // Update the counter when a new user connects socket.on('users', function(users) { userCount = document.getElementById('user_counter'); userCount.innerHTML = users.user_count; }); }); </script> <h1 id='user_counter'></h1> <!-- the rest of your template -->

话虽这么说,您不需要在您的render_template调用中传递计数器值. 另外,从flask-socketio 文档开始,看来似乎是一个好习惯应用程序的方式如下:

This being said, you don't need to pass the counter value in your render_template call. Also, from flask-socketio docs, it seems to be good practice to start your app in the following way:

if __name__ == "__main__": socketio.run(app)

此处指向示例的已编辑版本的链接.

Here a link to an edited version of your example.

更多推荐

如何在烧瓶中获得连接的客户端

本文发布于:2023-11-25 20:35:34,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1631255.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:烧瓶   客户端   如何在

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!