我试图通过ZMQ插座向Python服务器发送一些数据。Python服务器也使用ZMQ创建一个套接字。
```lang-python
打印(“连接统一工具包.”)
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind('tcp://*:5555')
而True:
request = socket.recv_multipart()
print("Somethings received");
req = json.loads(request[1])
print("Received from Unity Toolkit: ", req)
我尝试使用Python客户端与该服务器进行通信,它可以工作,但当我尝试使用Unity3D项目中的.NET ZMQ库进行通信时,有一个异常我不知道如何处理。给我的NETQMClient (这是来自一个旧项目的遗留代码,但我可以更改它)这样做:
```lang-csharp
//使用Thread()执行这一行
AsyncIO.ForceDotNet.Force();
requestSocket =新的RequestSocket();
requestSocket.Connect("tcp://192.162.0.104:5555");
isAvailable =真;
时间(!clientStopped){
//Debug.Log("Continuing");
}
requestSocket.Close();
NetMQConfig.Cleanup();
运行在线程上的函数的//结束
//.
//稍后,当按下按钮时
尝试{
//endpoint is a one-character string that
//the server uses as a cue for something
requestSocket.SendMoreFrame(endpoint);
requestSocket.SendFrame(request); //this a class turned into a JSON using JsonUtility.ToJson
} catch (System.Exception) {
Debug.Log("Something went wrong");
throw;
}
稍后,C#脚本等待响应,我处理该响应并使用它。问题是,我已经测试过它在同一台计算机上运行客户端和服务器,它可以工作。但是,当我将项目部署到真正的Hololens 2( NETQM客户端运行的地方)时,我会在Visual中得到这个错误。
我添加了try catch块,以查看是否存在一些奇怪的行为,但在这一点上也不例外。任何关于正确方向的提示都将不胜感激。
编辑:在这个项目中用于复制错误的全部脚本。
这个类保存稍后将转换为JSON的数据
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class Serialization {
public int numPanels;
public bool colorHarmony;
public float colorfulness;
[Serializable]
public Request(int numPanels, bool colorHarmony, float colorfulness) {
this.numPanels = numPanels;;
this.colorHarmony = colorHarmony;
this.colorfulness = colorfulness;
}
}
这是具有ZMQ逻辑的脚本
using System.Collections.Generic;
using System.Threading;
using NetMQ;
using NetMQ.Sockets;
using UnityEngine;
public class PythonNetworking {
private bool clientStopped;
private RequestSocket requestSocket;
private byte[] frame;
// for now only one request at a time is supported
public string requestResult;
private bool isAvailable;
public PythonNetworking() {
clientStopped = false;
var clientThread = new Thread(NetMQClient);
clientThread.Start();
}
public void StopClient() {
clientStopped = true;
}
// ReSharper disable once InconsistentNaming
private void NetMQClient() {
AsyncIO.ForceDotNet.Force();
requestSocket = new RequestSocket();
// Computer running the server which must receive the info
requestSocket.Connect("tcp://192.168.0.104:5555");
isAvailable = true;
while (!clientStopped)
{
//Debug.Log("Continuing");
}
requestSocket.Close();
NetMQConfig.Cleanup();
}
public void SetFrame(byte[] currFrame) {
frame = currFrame;
}
// Create queue of requests in case multiple have to be handled
private void SimpleRequest(string endpoint, string request) {
// wait until socket is available
while (!isAvailable) {
//Debug.Log("Socket unavailable");
}
isAvailable = false;
if (request == null) {
requestSocket.SendFrame(endpoint);
} else {
Debug.Log("Sending to Python server: " + request);
try
{
requestSocket.SendMoreFrame(endpoint);
Debug.Log("SendMoreFrame called");
requestSocket.SendFrame(request);
Debug.Log("SendFrame called");
}
catch (System.Exception)
{
Debug.Log("Something went wrong");
throw;
}
}
var msg = requestSocket.ReceiveFrameBytes();
Debug.Log("ReceiveFrameBytes returned a value");
isAvailable = true;
requestResult = System.Text.Encoding.UTF8.GetString(msg);
}
public void PerformRequest(string endpoint, string request) {
requestResult = null;
var requestThread = new Thread(() => SimpleRequest(endpoint, request));
requestThread.Start();
}
}
这是在触发事件时发出请求的脚本:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Microsoft.MixedReality.Toolkit.Input;
using Microsoft.MixedReality.Toolkit.UI;
using Newtonsoft.Json;
public class MyTool: MonoBehaviour {
private PythonNetworking pythonNetworking;
public struct PanelConstraints {
public string name;
public float height;
public float width;
}
public void Start() {
pythonNetworking = new PythonNetworking();
Debug.Log("Tool initialized!");
//called here for debugging purposes, this method is called when a button is pressed
SubmitConstraints();
}
//When a button is pressed
public void SubmitConstraints() {
Debug.Log("Submitting constraints...");
StartCoroutine(CreateRequest("P"));
}
private IEnumerator CreateRequest(string type) {
Serialization.Request request = new Serialization.Request(1, false, 1.0f);
var requestJson = JsonUtility.ToJson(request);
pythonNetworking.PerformRequest(type, requestJson);
yield return new WaitUntil(() => pythonNetworking.requestResult != null);
if (type == "P") {
panelData = JsonConvert.DeserializeObject<List<string>>(pythonNetworking.requestResult);
}
}
}
最后,Python服务器代码是:
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind('tcp://*:5555')
while True:
request = socket.recv_multipart()
print("Somethings received");
req = json.loads(request[1])
#Data is processed
根据设置,我使用Unity2019.4.26f1,我创建了一个3D场景,向它添加了一个GameObject
,我将脚本MyTool.cs
附加到它上,并在前面的GameObject
下附加了一个按钮。单击该按钮时,将调用SubmitContrainst()
方法(为了调试目的,现在在Start()
中自动调用该方法)。这个场景是使用VisualStudio2019在Hololens 2中部署的(尽管我尝试在“游戏模式”中运行它,与另一台计算机通信以重新创建部署环境,即在不同设备中与客户端和服务器以及库的不同实现进行通信)。当应用程序即将在Hololens中启动时,抛出我前面介绍的异常(请参阅屏幕截图)。使用PythonVersion3.10.4运行的Python没有收到任何信息。TCP通信似乎有效,因为当我在不同的主机上运行两个Python脚本(使用REQ
和REP
与ZMQ进行客户机/服务器通信)时,它可以工作,但我觉得这种通信在Hololens 2上不起作用。但这感觉很奇怪,因为我已经设法将Hololens 2与另一个设备(使用另一个库Windows.Networking.Socket
)进行通信。
发布于 2022-06-02 21:55:28
是否导航到设置,->发布设置,以检查项目的功能,并确保根据目的启用了Internet或。它还可以在C#项目的清单文件中进行检查和修改。
抛出的异常周围的代码更像是Unity,您需要添加断点来查看这个问题是否是由失败的套接字连接引起的。
此外,您还可以参考关于Web套接字客户端断开UWP构建中抛出的异常- Unity的讨论。
https://stackoverflow.com/questions/72352910
复制相似问题