Flutter StreamBuilder和Python TCP套接字服务器无法连接

时间:2020-05-08 20:22:18

标签: flutter

我正在尝试为物联网应用程序编写一个流畅的应用程序。移动设备将通过WiFi连接到硬件,并且数据将通过tcp套接字发送。物联网硬件正在开发中,但我需要开始使用该应用程序。

我在运行一个套接字并输出2个已稍微随机化的正弦波的python脚本方面获得了一些帮助。它运行良好,并且我有一个连接到它的python主机脚本并在数据通过时对其进行绘图。我要假装这是传感器数据,所以我想通过颤动连接到该数据,以便可以在UI等上开始工作。

我已经尝试了1000件事,但是大部分工作是通过https://flutter.dev/docs/cookbook/networking/web-sockets完成的。

我尝试的另一件事是在socket.io中使用nodejs,并确实使用adhara_socket_io包与flutter进行了通信,但是那里有太多抽象,我担心它不能复制从硬件中得到的东西。

这是python代码:

import queue
import time

#import matplotlib.pyplot as plt
import math
from queue import Queue

import numpy as np
import random
import socket
import threading
import asyncio


# A Queue in which the wave threads will store their values
# We will use this queue to get the data we need to send to our clients
Q = queue.Queue()

# replace this with your own host ip
HOST = '192.168.0.13'
PORT = 65432
Afrequency = float(input('give the frequency of the data output wave A: '))
Aperiod = int(input('give the output period (multiples of pi) of wave A: '))
Bfrequency = float(input('give the frequency of data output wave B: '))
Bperiod = int(input('give the output period (multiples of pi) of wave B: '))

# this function will continuosly generate x and y values for a given sine wave
# it waits 1/freq seconds so our frequency matches the given input


def generateTuples(name, outputfrequency, outputperiod):

    sincurveshift = 10
    rmax = 1.25
    rmin = 0.75
    outputperiod = outputperiod * math.pi
    numberOfPoints = outputfrequency * outputperiod
    increment = (2 * math.pi) / numberOfPoints
    xcounter = 0

    while True:
        jitterValue = rmin + (random.random() * (rmax - rmin))
        x = xcounter * increment
        sinValue = 5 * math.sin(x) + sincurveshift * jitterValue
        partOfTheMessage = '%s(%09.2f,%09.2f)*' % (name, x, sinValue)
        xcounter += 1
        Q.put(partOfTheMessage)
        time.sleep(1/outputfrequency)


# this is a thread that will be created each time a client connects
# it sends the total string with values from wave A and B
class clientThread(threading.Thread):
    def __init__(self, clientAddress, clientSocket, q):
        threading.Thread.__init__(self)
        self.clientSocket = clientSocket

        print("New client connected with address: " + str(clientAddress))

    def run(self):
        while True:
            self.clientSocket.send(bytes(Q.get(), 'utf-8'))
            time.sleep(0.1)


def main():
    # first we start up 2 threads that will each generate a y value every 1/freq seconds
    # we let them run in the background so we can move on to listening for clients
    print('starting sine wave 1')
    print('starting sine wave 2')
    wave1 = threading.Thread(target=generateTuples, args=(
        'A', Afrequency, Aperiod), daemon=True)
    wave2 = threading.Thread(target=generateTuples, args=(
        'B', Bfrequency, Bperiod), daemon=True)
    wave1.start()
    wave2.start()
    time.sleep(1)

    print('starting transmission')

    # here we set up the host
    # we continously look for clients and give each of them their own thread
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((HOST, PORT))
        s.listen()
        while True:
            conn, addr = s.accept()
            client = clientThread(addr, conn, queue)
            client.start()


if __name__ == "__main__":

    main()

这是我的颤动代码。

import 'package:flutter/foundation.dart';
import 'package:web_socket_channel/io.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
// This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'MyApp Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'MyApp Mobile'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final channel = IOWebSocketChannel.connect('ws://192.168.0.13:65432');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
          child: StreamBuilder(
        stream: channel.stream,
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
            case ConnectionState.none:
              print('trying to connect');
              return LinearProgressIndicator();
            case ConnectionState.active:
              print("OMG ITS CONNECTED");
              print(snapshot.data);
              return Text(snapshot.data);
            case ConnectionState.done:
              return Text('Its done ${snapshot.data}');
          }

          return Text(snapshot.hasData ? '${snapshot.data}' : 'No Data');
        },
      )),
    );
  }
}

我正在用手机运行正在开发中的应用程序-不确定这是否有用。 任何帮助将不胜感激!

N

编辑- 我现在在python控制台中看到一个错误:

New client connected with address: ('192.168.0.16', 65020)
Exception in thread Thread-24:
Traceback (most recent call last):
  File "C:\Users\nickc\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
    self.run()
  File "host.py", line 62, in run
    self.clientSocket.send(bytes(Q.get(), 'utf-8'))
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine

因此看起来好像已经连接,然后中止了连接?

就像shubham在答案中已经提到的那样,我可以成功连接并使用以下命令将输入​​数据打印到控制台:

Socket socket = await Socket.connect(host, port);
socket.listen((event) {
  print(String.fromCharCodes(event));
});

1 个答案:

答案 0 :(得分:0)

我对Web套接字通道程序包了解不多,但是当我尝试运行您的代码时,一旦我的客户端(电话)连接并经过了{{3 }}我认为客户端套接字会以某种方式关闭。

但是我可以使用dart的套接字包连接到您的python套接字 这是代码

Socket socket = await Socket.connect(host, port);
socket.listen((event) {
  log(String.fromCharCodes(event));
});

这是我得到的输出

[log] B(000051.07,000013.89)*
[log] B(000051.11,000013.26)*
[log] B(000051.14,000016.09)*
[log] B(000051.18,000013.77)*
[log] B(000051.21,000015.63)*
[log] B(000051.25,000013.78)*
[log] B(000051.29,000013.49)*
[log] B(000051.32,000016.75)*
[log] A(000103.50,000012.36)*
[log] A(000103.58,000009.93)*
[log] A(000103.67,000007.72)*
[log] A(000103.75,000009.02)*
[log] A(000103.83,000008.28)*