本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
服務傳入流量
您可以透過在應用程式程式碼旁邊執行 HTTP 伺服器,在本機監視或偵錯應用程式。為了提供外部流量,您可以將 AWS Panorama 設備上的連接埠對應到應用程式容器上的連接埠。
重要
根據預設,AWS Panorama 設備不接受任何連接埠上的傳入流量。在應用裝置上開啟連接埠存在隱含的安全風險。使用此功能時,您必須採取其他步驟保護您的設備免受外部流量的影響以及授權用戶端與設備之間的安全通訊。
本指南隨附的範例程式碼僅用於示範目的,不會實作驗證、授權或加密。
您可以在設備上開啟範圍為 8000-9000 的連接埠。這些連接埠在開啟時,可以接收來自任何可路由用戶端的流量。部署應用程式時,您可以指定要開啟的連接埠,並將應用裝置上的連接埠對應至應用程式容器上的連接埠。設備軟體會將流量轉送至容器,並將回應傳送回應給要求者。要求會在您指定的設備連接埠上接收,而回應則會在隨機暫時連接埠上傳出。
設定傳入連接埠
您可以在應用程式組態中的三個位置指定連接埠對應。該代碼包的package.json
時,您可以指定程式碼節點偵聽的連接埠network
區塊。下列範例宣告節點在連接埠 80 上偵聽。
範例 套件 /123456789012-除錯 _ 伺服器
"outputs": [ { "description": "Video stream output", "name": "video_out", "type": "media" } ],
"network": { "inboundPorts": [ { "port": 80, "description": "http" } ] }
在應用程式資訊清單中,您可以宣告將應用裝置上的連接埠對應至應用程式程式碼容器上的連接埠的路由規則。下列範例會新增將裝置上的連接埠 8080 對應至code_node
容器。
範例 圖形/我的應用程序/圖形.json
{ "producer": "model_input_width", "consumer": "code_node.model_input_width" }, { "producer": "model_input_order", "consumer": "code_node.model_input_order" } ],
"networkRoutingRules": [ { "node": "code_node", "containerPort": 80, "hostPort": 8080, "decorator": { "title": "Listener port 8080", "description": "Container monitoring and debug." } } ]
部署應用程式時,您可以在 AWS Panorama 主控台中指定相同的規則,或是使用覆寫文件傳遞給CreateApplicationInstanceAPI。您必須在部署時提供此組態,以確認要在應用裝置上開啟連接埠。
範例 圖形/我的應用程序/覆蓋.json
{ "replace": "camera_node", "with": [ { "name": "exterior-north" } ] } ],
"networkRoutingRules":[ { "node": "code_node", "containerPort": 80, "hostPort": 8080 } ]
, "envelopeVersion": "2021-01-01" } }
如果應用程式資訊清單中指定的裝置連接埠正在被其他應用程式使用,您可以使用覆寫文件來選擇不同的連接埠。
服務流量
在容器上開啟連接埠的情況下,您可以開啟通訊端或執行伺服器來處理傳入的要求。所以此debug-server
範例顯示與電腦視覺應用程式程式碼一起執行的 HTTP 伺服器的基本實作。
重要
示例實現對於生產使用不安全。為避免讓您的裝置容易受到攻擊,您必須在程式碼和網路設定中實作適當的安全性控制。
範例 套件 /123456789012-除錯 _ 伺服器 -1.0/應用程式.PY — HTTP 伺服器
# HTTP debug server def run_debugger(self): """Process debug commands from local network.""" class ServerHandler(SimpleHTTPRequestHandler): # Store reference to application application = self # Get status def do_GET(self): """Process GET requests.""" logger.info('Get request to {}'.format(self.path)) if self.path == '/status': self.send_200('OK') else: self.send_error(400) # Restart application def do_POST(self): """Process POST requests.""" logger.info('Post request to {}'.format(self.path)) if self.path == '/restart': self.send_200('OK') ServerHandler.application.stop() else: self.send_error(400) # Send response def send_200(self, msg): """Send 200 (success) response with message.""" self.send_response(200) self.send_header('Content-Type', 'text/plain') self.end_headers() self.wfile.write(msg.encode('utf-8')) try: # Run HTTP server self.server = HTTPServer(("", self.CONTAINER_PORT), ServerHandler) self.server.serve_forever(1) # Server shut down by run_cv loop logger.info("EXITING SERVER THREAD") except: logger.exception('Exception on server thread.')
服務器接受 GET 請求/status
路徑來檢索有關應用程序的一些信息。它也接受 POST 請求/restart
以重新啟動應用程式。
為了示範此功能,範例應用程式會在個別執行緒上執行 HTTP 用戶端。用戶端呼叫/status
啟動後不久通過本地網絡的路徑,並在幾分鐘後重新啟動應用程序。
範例 套件 /123456789012-除錯 _ 伺服器 -1.0/應用程式.PY — HTTP 用戶端
# HTTP test client def run_client(self): """Send HTTP requests to device port to demnostrate debug server functions.""" def client_get(): """Get container status""" r = requests.get('http://{}:{}/status'.format(self.device_ip, self.DEVICE_PORT)) logger.info('Response: {}'.format(r.text)) return def client_post(): """Restart application""" r = requests.post('http://{}:{}/restart'.format(self.device_ip, self.DEVICE_PORT)) logger.info('Response: {}'.format(r.text)) return # Call debug server while not self.terminate: try: time.sleep(30) client_get() time.sleep(300) client_post() except: logger.exception('Exception on client thread.') # stop signal received logger.info("EXITING CLIENT THREAD")
主循環管理線程並在退出時重新啟動應用程序。
範例 套件 /123456789012-除錯 _ 伺服器 -1.0/應用程式.PY — 主要迴圈
def main(): panorama = panoramasdk.node() while True: try: # Instantiate application logger.info('INITIALIZING APPLICATION') app = Application(panorama) # Create threads for stream processing, debugger, and client app.run_thread = threading.Thread(target=app.run_cv) app.server_thread = threading.Thread(target=app.run_debugger) app.client_thread = threading.Thread(target=app.run_client) # Start threads logger.info('RUNNING APPLICATION') app.run_thread.start() logger.info('RUNNING SERVER') app.server_thread.start() logger.info('RUNNING CLIENT') app.client_thread.start() # Wait for threads to exit app.run_thread.join() app.server_thread.join() app.client_thread.join() logger.info('RESTARTING APPLICATION') except: logger.exception('Exception during processing loop.')
若要部署範例應用程式,請參閱本指南中的說明 GitHub 儲存庫。