TCP-клиент iOS с предупреждениями о потоках сервера PythonIOS

Программируем под IOS
Ответить
Anonymous
 TCP-клиент iOS с предупреждениями о потоках сервера Python

Сообщение Anonymous »

У меня вопрос, связанный с правильным управлением интенсивными задачами, например подключением к серверу для клиентского приложения iOS. У меня есть сервер, работающий на Python. Ниже приведен код клиента и сервера.
При использовании текущего кода я получаю следующее предупреждение:
Thread Performance Checker: Thread running at User-interactive quality-of-service class waiting on a thread without a QoS class specified (base priority 33). Investigate ways to avoid priority inversions
PID: 31921, TID: 17707895
Backtrace
=================================================================
3 CFNetwork 0x000000019baeca08 estimatedPropertyListSize + 37652
4 CFNetwork 0x000000019b9573a8 cfnTranslateCFError + 2688
5 libdispatch.dylib 0x00000001019e67bc _dispatch_client_callout + 20
6 libdispatch.dylib 0x00000001019e834c _dispatch_once_callout + 140
7 CFNetwork 0x000000019b95737c cfnTranslateCFError + 2644
8 CFNetwork 0x000000019baec8c8 estimatedPropertyListSize + 37332
9 libdispatch.dylib 0x00000001019e67bc _dispatch_client_callout + 20
10 libdispatch.dylib 0x00000001019e834c _dispatch_once_callout + 140
11 CFNetwork 0x000000019baec790 estimatedPropertyListSize + 37020
12 CFNetwork 0x000000019baec81c estimatedPropertyListSize + 37160
13 libdispatch.dylib 0x00000001019e67bc _dispatch_client_callout + 20
14 libdispatch.dylib 0x00000001019e834c _dispatch_once_callout + 140
15 CFNetwork 0x000000019baec804 estimatedPropertyListSize + 37136
16 CFNetwork 0x000000019b9ac498 _CFStreamErrorFromCFError + 248272
17 CoreFoundation 0x000000019a7bd568 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 406888
18 LFA QUANTIFICATION 0x000000010090e490 $s18LFA_QUANTIFICATION6ClientC7connectyyF + 1648
19 LFA QUANTIFICATION 0x0000000100914294 $s18LFA_QUANTIFICATION4HomeC12logOutButtonyySo8UIButtonCF + 132
20 LFA QUANTIFICATION 0x000000010091440c $s18LFA_QUANTIFICATION4HomeC12logOutButtonyySo8UIButtonCFTo + 52
21 UIKitCore 0x000000019d807f78 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 14884728
22 UIKitCore 0x000000019d19c698 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8152728
23 UIKitCore 0x000000019d19ca10 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8153616
24 UIKitCore 0x000000019d199f0c 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8142604
25 UIKitCore 0x000000019d19ba78 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8149624
26 UIKitCore 0x000000019cbd74c0 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2102464
27 UIKitCore 0x000000019cbd6e64 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2100836
28 UIKitCore 0x000000019cbd60e4 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2097380
29 UIKitCore 0x000000019cb98970 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 1845616
30 UIKitCore 0x000000019cb97010 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 1839120
31 UIKitCore 0x000000019cb95a1c 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 1833500
32 UIKitCore 0x000000019ca80d78 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 699768
33 UIKitCore 0x000000019ca80468 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 697448
34 UIKitCore 0x000000019ca80524 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 697636
35 CoreFoundation 0x000000019a79162c 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 226860
36 CoreFoundation 0x000000019a7908a8 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 223400
37 CoreFoundation 0x000000019a78f058 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 217176
38 CoreFoundation 0x000000019a78dd88 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 212360
39 CoreFoundation 0x000000019a78d968 CFRunLoopRunSpecific + 608
40 GraphicsServices 0x00000001dea834e0 GSEventRunModal + 164
41 UIKitCore 0x000000019cc00edc 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2272988
42 UIKitCore 0x000000019cc00518 UIApplicationMain + 340
43 UIKitCore 0x000000019ce39734 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 4601652
44 LFA QUANTIFICATION 0x000000010090ca10 $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 120
45 LFA QUANTIFICATION 0x000000010090c988 $s18LFA_QUANTIFICATION11AppDelegateC5$mainyyFZ + 44
46 LFA QUANTIFICATION 0x000000010090ca8c main + 28
47 dyld 0x00000001bdcaed84 7BE2B757-3B3D-3E91-8CB7-74F3887660C7 + 23940


Я довольно много читал об этом и экспериментировал, и я попытался решить эту проблему, используя DispathQueues для запуска в фоновом режиме следующего кода, который вызывает клиентский класс (из другого представления) контроллер):
@IBAction func logOutButton(_ sender: UIButton) {

DispatchQueue.global(qos: .background).async {
self.clientSession.connect()
self.clientSession.send(message: "IMAGE")
self.clientSession.send(message: "Leaving")
self.clientSession.send(message: "!")
}
}

Используя флаг .async, мне удалось убрать предупреждения, но тогда клиент не смог получить входные данные с моего сервера (по крайней мере, я не смог распечатать сообщение это было получено). Я проверяю серверную часть: сервер как обычно получал и отправлял данные обратно клиенту iOS. Вообще говоря, работа с асинхронным режимом всегда выдавала предупреждение, но клиент, похоже, не мог правильно ответить серверу (т. е. зависал/не получал сообщения сервера).
Мой главный вопрос заключается в следующем. : как мне убрать эти предупреждения, не влияя на возможность клиента получать сообщения с сервера? Не похоже, что предупреждения нарушают функциональность приложения, но мне хотелось бы знать, почему возникают эти проблемы и какое рекомендуемое решение? Я подозреваю, что я неправильно использую DispatchQueues или неправильно планирую RunLoops, но это может быть не так.
Любые рекомендации в любом случае будут полезны.
Текущий код:
//
// Client.swift
// LFA QUANTIFICATION

import UIKit

class Client: NSObject {
var inputStream: InputStream!
var outputStream: OutputStream!

weak var delegate: ChatRoomDelegate?

var username = ""

let maxBufferLength = 4096

func connect() {
var readStream: Unmanaged?
var writeStream: Unmanaged?

CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, ("ADDR" as CFString), PORT, &readStream, &writeStream) // placeholder for ADDR and PORT, filled in correctly when running

inputStream = readStream!.takeRetainedValue()
outputStream = writeStream!.takeRetainedValue()

inputStream.delegate = self
outputStream.delegate = self

inputStream.schedule(in: .current, forMode: .common)
outputStream.schedule(in: .current, forMode: .common)

inputStream.open()
outputStream.open()
}

func byteArray(from value: T) -> [UInt8] where T: FixedWidthInteger {
withUnsafeBytes(of: value.bigEndian, Array.init)
}

func send(message: String) {
let lengthStr : Int32 = Int32(message.count)
let bytes : [UInt8] = byteArray(from: lengthStr)
outputStream.write(bytes, maxLength: bytes.count) // send length of the message

// send the message
if let _ = message.data(using: .ascii) {
outputStream.write(message, maxLength: Int(lengthStr))
}

}

}
extension Client: StreamDelegate {
func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
switch eventCode {
case .openCompleted:
print("Stream Opened")
case .hasBytesAvailable:
print("here")
if aStream == inputStream {
recieveData()
}
case .errorOccurred:
print("Error")
case .endEncountered:
print("END")
default:
break
}
}

func recieveData() {
var buffer = [UInt8](repeating: 0, count: 1024)
let bytesRead = inputStream.read(&buffer, maxLength: buffer.count)
if bytesRead > 0 {
let recievedData = Data(buffer.prefix(bytesRead))
guard let recievedString = String(data: recievedData, encoding: .utf8) else { return }
self.delegate?.recieved(message: recievedString)

}
}

}

protocol ChatRoomDelegate: AnyObject {
func recieved(message: String)
}


// Server.py

import threading
import socket

UNKNOWN_BUFFER_LENGTH = 1024
PORT = 5050
SERVER = "localhost"
ADDR = (SERVER, PORT)
FORMAT = "utf-8"
DISCONNECT_MESSAGE = "!"

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)

clients = set()
# List of all current client connnections
clients_lock = threading.Lock()

def receive_message(conn):
# Receive 4 bytes from the socket
data = conn.recv(4)

# Convert the received bytes to an integer using big-endian byte order
received_integer = int.from_bytes(data, byteorder='big')
msg = conn.recv(received_integer).decode(FORMAT)

return msg

def process_image(conn, addr):
print("Here")
message = f"[{addr}] Recieved Incoming Message"
conn.sendall(message.encode(FORMAT))
print("Sent message")

def handle_client(conn, addr):

print(f"[NEW CONNECTION] {addr} Connected")

try:
connected = True
while connected:
msg = receive_message(conn)
if msg == "IMAGE":
process_image(conn, addr)
if not msg:
break

if msg == DISCONNECT_MESSAGE:
connected = False

print(f"[{addr}] {msg}")

finally:
with clients_lock:
clients.remove(conn)

conn.close()

def start():
print('[SERVER STARTED]')
server.listen()
while True:
conn, addr = server.accept()
with clients_lock:
clients.add(conn)
print(f'[CONNENCTED CLIENTS] {len(clients)}')
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()

start()

\\ View Controller that Calls the Client class, with the code snippet discussed above (where I tried to fix with async)

//
// Home.swift
// LFA QUANTIFICATION

import UIKit

class Home: UIViewController {

let clientSession = Client()

@IBOutlet weak var cameraPhotoButton: UIButton!

@IBOutlet weak var homeText: UILabel!

var user: String!

override func viewDidLoad() {
super.viewDidLoad()
clientSession.delegate = self
homeText.text = "Hello " + user + "! How are you feeling today?"
homeText.numberOfLines = 5
// Button Appearance properties
cameraPhotoButton.titleLabel!.textAlignment = .center
cameraPhotoButton.titleLabel!.numberOfLines = 0

}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}

@IBAction func capturePhoto(_ sender: UIButton) {
guard let vc = storyboard?.instantiateViewController(withIdentifier: "cam") as? Camera else {
return
}
vc.modalPresentationStyle = .fullScreen
present(vc, animated: true, completion: nil)
}
@IBAction func logOutButton(_ sender: UIButton) {
self.clientSession.connect()
self.clientSession.send(message: "IMAGE")
self.clientSession.send(message: "Leaving")
self.clientSession.send(message: "!")
}

//clientSession.send(message: "hello")
//clientSession.send(message: "!")

}

extension Home: ChatRoomDelegate {
func recieved(message: String) {
print("Chatroom: ", message)
}
}



Подробнее здесь: https://stackoverflow.com/questions/785 ... d-warnings
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»