MicroPython Socket TCP链接记录二 全局采集数据

MicroPython Socket TCP链接记录二 全局采集数据

模拟测试 ,非生产日用, 生产最终选择使用简单的http来实现数据采集定时上报到后端,后端根据最后数据上传时间来判断设备是否掉线,毕竟花时间调试完socket了后,公司试用了下觉得不行那就浪费时间了

在这里插入图片描述

socketserver全局下发命令到客户端 完成数据采集并上传

因为手上暂时没有很多设备,所以先用电脑的异步客户端模拟设备,服务器发送ping命令,客户端返回pong+id

模拟设备掉线

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码如下

服务端

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2021/3/25 10:26
# @Author  : Link
# @Site    : 服务端
# @File    : socket_server.py
# @Software: PyCharm

from socketserver import BaseRequestHandler, ThreadingTCPServer

import threading

from queue import Queue
from time import sleep

queue = Queue(maxsize=10)
connect_queen = {}  # 每新建一个链接 则维护一个queue


def broadcast_queue_th():
    while True:
        inst = input("请输入下发命令(直接回车关闭链接)>>> :")
        queue.put(inst)

        inst = queue.get()
        for _, _queue in connect_queen.items():
            _queue.put(inst)


class Handler(BaseRequestHandler):

    # def handle(self) -> None:
    #     address, pid = self.client_address
    #     print("%s connected! pid: %s" % (address, pid))
    #     while True:
    #         try:
    #             data = self.request.recv(1024)
    #             if not data: break
    #             print('->pid:%s say client:%s' % (pid, data))
    #             self.request.send(data.upper())
    #         except ConnectionError:
    #             print('->pid:%s close connect' % (pid))
    #             break
    #     print("request close\n")
    #     self.request.close()

    # 启动一个用于发布全局数据的链接
    def handle(self) -> None:
        address, pid = self.client_address
        connect_queen[pid] = Queue(maxsize=2)
        while True:
            try:
                data = connect_queen[pid].get()
                if not data: break #断开链接
                self.request.send(data.encode('utf-8'))
                recv = self.request.recv(30).decode("utf-8")  # 等待数据 阻塞
                if recv:
                    print(recv)
                    self.request.send("33".encode('utf-8'))
                sleep(.2)
            except ConnectionError:
                break
        del connect_queen[pid]
        self.request.close()


if __name__ == '__main__':
    # 启动数据发布进程
    th = threading.Thread(target=broadcast_queue_th, name="thi")
    th.start()
    # 启动服务器
    server = ThreadingTCPServer(('0.0.0.0', 8080), Handler)
    server.serve_forever()  # 链接循环

客户端

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2021/3/26 15:56
# @Author  : Link
# @Site    : 客户端
# @File    : socket_client.py
# @Software: PyCharm

import socket
import asyncio
import random

# 创建十个测试链接
clients = [socket.socket(socket.AF_INET, socket.SOCK_STREAM) for _ in range(10)]
for client in clients:
    client.connect(('127.0.0.1', 8080))


async def client_connect_server_send(client, i):
    while True:
        client.send(f'hello{i}'.encode('utf-8'))
        print(client.recv(1024).decode("utf-8"))
        await asyncio.sleep(.5)
    # client.close()


async def client_connect_server_recv(client, i):
    sl = 0
    sl_t = random.randint(10, 20)
    equipment = "micro{}".format(i)
    while True:
        sl += 1
        if sl >= sl_t:
            print("micro{} connect close!".format(i))
            break
        data = client.recv(36).decode("utf-8") # 服务器断开链接后会一直返回空,没有断开就会阻塞住
        if data:
            # 获取到服务器发送来的全局指令
            send_data = equipment_exec(equipment, data).encode('utf-8')
            client.send(send_data)
            # 服务器上传数据后解析成功返回33
            res = client.recv(10).decode("utf-8")
            if res == "33":
                print("success")
            else:
                print(res)
        else:
            print("micro{} connect close!".format(i))
            break
        await asyncio.sleep(.5)
    client.close()


def equipment_exec(equipment: str, inst: str) -> str:
    """
    每次获取到服务器的指令后 都要进行返回
    """
    if inst == "hello":
        return "this is %s" % equipment
    if inst == "ping":
        return "pong %s" % equipment
    return "nothing"


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    tasks = [client_connect_server_recv(client=client, i=index) for index, client in enumerate(clients)]
    loop.run_until_complete(asyncio.wait(tasks))

先启动服务端,再启动客户端,手动在客户端发送命令测试,客户端在接收到十到二十次数据后会断线

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值