使用 Expo 应用程序在本地服务器上请求失败

问题描述 投票:0回答:1

我这里遇到了一点麻烦

我创建了一个在我的个人计算机上运行的 Flask 服务器,IP 地址为 192.168.1.3:5000,它本身运行得很好。我使用 Insomnia 和网络测试了这些请求,一切都很完美。

但是,当从我的智能手机上的 Expo 应用程序发出请求时,它们不起作用。这就好像应用程序无法访问本地网络请求或类似的东西。

我做了一些研究,在 app.json 文件中找到了有关权限的信息。我按照建议进行了更改,但没有成功。我仍然只能从桌面访问。

还值得一提的是,如果我通过智能手机的网络浏览器访问同一端点,我可以看到我在服务器的“/”路由中插入的“hello world”消息。所以,我不认为这是我机器的 IP 或本地网络内设备之间的通信问题。

这是一些代码:

我的烧瓶服务器:

from flask import Flask, request
from ctypes import windll
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
from flask_cors import CORS
import requests

app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})

VLC_PASSWORD = 'vlcpassword'
VLC_URL = 'http://localhost:8080/requests/status.json'
VK_MEDIA_PLAY_PAUSE = 0xB3
VK_VOLUME_UP = 0xAF
VK_VOLUME_DOWN = 0xAE

def press_key(hexKeyCode):
    windll.user32.keybd_event(hexKeyCode, 0, 0, 0)
    windll.user32.keybd_event(hexKeyCode, 0, 2, 0)

def set_volume(level):
    devices = AudioUtilities.GetSpeakers()
    interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
    volume = interface.QueryInterface(IAudioEndpointVolume)
    volume.SetMasterVolumeLevelScalar(level, None)

def send_vlc_command(command):
  url = f'http://localhost:8080/requests/status.json?command={command}'
  response = requests.get(url, auth=('', VLC_PASSWORD))
  return response.status_code == 200

@app.route('/play_pause', methods=['POST'])
def play_pause():
  data = request.get_json()
  is_vlc = data.get('is_vlc', "False")
  if is_vlc == "True":
    send_vlc_command('pl_pause')
    return 'VLC play/pause triggered'
  else:
    press_key(VK_MEDIA_PLAY_PAUSE)
    return 'Play/pause triggered'

@app.route('/volume_up', methods=['POST'])
def volume_up():
  data = request.get_json()
  is_vlc = data.get('is_vlc', False)
  if is_vlc == "True":
    send_vlc_command('volume&val=%2B20')
    return 'VLC volume up triggered'
  else:
    press_key(VK_VOLUME_UP)
    return 'Volume up triggered'

@app.route('/volume_down', methods=['POST'])
def vlc_volume_down():
  data = request.get_json()
  is_vlc = data.get('is_vlc', False)
  if is_vlc == "True":
    send_vlc_command('volume&val=-20')
    return 'VLC volume down triggered'
  else:
    press_key(VK_VOLUME_DOWN)
    return 'Volume down triggered'
  
@app.route('/')
def hello():
  return "Hello, World!"

if __name__ == '__main__':
    app.run(host='192.168.1.3', port=5000)

我的 expo 应用程序中的 index.tsx:

import React, { useState } from 'react';
import CustomButton from '../../components/CustomButton';
import { StyleSheet, View, Text, Switch } from 'react-native';
import axios from 'axios';

const TabOneScreen = () => {
  const [isVLC, setIsVLC] = useState(false); 
  const [serverIsOnline, setServerIsOnline] = useState(false); 
  const [log, setLog] = useState<any[]>([]); 
  const vlcServerURL = 'http://192.168.1.3:5000'; 

  const handlePlayPause = async () => {
    try {
      const response = await axios.post(vlcServerURL + '/play_pause', {
        is_vlc: isVLC ? 'True' : 'False'
      });
      console.log(response.data);
      setLog([...log, response.data]);
      setLog([...log, response.status]);
    } catch (error) {
      console.error('Fail:', error);
    }
  };

  const handleVolumeUp = async () => {
    try {
      const response = await axios.post(vlcServerURL + '/volume_up', {
          is_vlc: isVLC ? 'True' : 'False',
      });
      console.log(response.data);
    } catch (error) {
      console.error('Fail:', error);
    }
  };

  const handleVolumeDown = async () => {
    try {
      const response = await axios.post(vlcServerURL + '/volume_down', {
        is_vlc: isVLC ? 'True' : 'False'
      });
      console.log(response.data);
    } catch (error) {
      console.error('Fail:', error);
    }
  };

  const testConnection = async () => {
    try {
      console.log(vlcServerURL)
      const response = await axios.get(vlcServerURL + '/');
      setLog([...log, response.data]);
      if (response.status === 200) {
        setServerIsOnline(true);
      }
    } catch (error) {
      console.error('Failure on connection:', error);
    }
  };

  React.useEffect(() => {
    testConnection();
  }, []);

  return (
   visual things here ...
  );
};



export default TabOneScreen;

我的 app.json android 权限:

"android": {
      "adaptiveIcon": {
        "foregroundImage": "./assets/images/adaptive-icon.png",
        "backgroundColor": "#ffffff"
      },
      "package": "com.teago.tvpccontrol",
      "permissions": ["INTERNET", "ACCESS_NETWORK_STATE"]
    },`
react-native flask expo
1个回答
0
投票

我做到了!!!

经过多次尝试,我终于解决了这个问题。根据世博论坛here上的这篇文章,需要将一个插件/属性添加到应用程序中,以便可以完成请求。老实说,我还没有深入研究真正的问题是什么,但对于那些和我有同样问题的人来说,这是解决方案。只需将以下代码片段添加到您的

app.json
:

"plugins": [
  [
    "expo-build-properties",
    {
      "android": {
        "usesCleartextTraffic": true
      }
    }
  ]
]
© www.soinside.com 2019 - 2024. All rights reserved.