Unity3D アプリケーションと Java (Jason) アプリケーションの間で (Java 部分で「BufferedOutputStream」を使用し、C# 部分で「NetworkStream」を使用して) ソケット ネットワーキングを作成しようとしています。これら 2 つのモジュールは相互に通信する必要があります。コードの Java 部分は次のとおりです。
public static void SendExecuteAction(String ag, Structure structure, Object tempObject, ClassEnv classEnv)
{
if(!agentThreadList.containsKey(ag))
{
AgentServiceThread ast = new AgentServiceThread(s, agentThreadList.size() - 1, ag, structure, tempObject, classEnv);
agentThreadList.put(ag, ast);
if(ast.getState() != Thread.State.BLOCKED)
ast.start();
try {
ast.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
agentThreadList.get(ag).start();
}
}
}
class AgentServiceThread extends Thread
{
Socket agentSocket;
int agentID = -1;
String agent;
Structure structure;
Object blockObject;
byte[] ba;
ClassEnv classEnv;
InputStream is;
BufferedOutputStream bos;
ToByteConvertHelper toBytes;
FromByteConvertHelper fromBytes;
AgentServiceThread(Socket s, int i, String ag, Structure structure, Object object, ClassEnv classEnv)
{
agentSocket = s;
agentID = i;
agent = ag;
this.structure = structure;
blockObject = object;
this.classEnv = classEnv;
try
{
toBytes = new ToByteConvertHelper();
fromBytes = new FromByteConvertHelper();
is = agentSocket.getInputStream();
bos = new BufferedOutputStream(agentSocket.getOutputStream());
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void run()
{
VCActionRequest vcar;
List<String> termList = new ArrayList<String>();
List<Term> structureTermList = structure.getTerms();
for(int i = 0; i < structureTermList.size(); i++)
{
termList.add(structureTermList.get(i).toString());
}
vcar = new VCActionRequest(agent, structure.getFunctor(), (ArrayList<String>)termList);
vcar.requestEnum = RequestEnum.ExecuteActions.index();
System.out.println("agent: " + agent + " action: " + structure.getFunctor());
ba = toBytes.toByte(vcar);
try
{
bos.write(ba);
bos.flush();
}
catch (IOException e)
{
e.printStackTrace();
}
synchronized(blockObject)
{
try
{
ba = new byte[1000];
is.read(ba, 0, 1000);
@SuppressWarnings("unchecked")
ArrayList<VCPerception> result = (ArrayList<VCPerception>)fromBytes.fromByte(ba);
classEnv.UpdatePercepts(result);
}
catch (IOException e1)
{
System.out.println(e1.toString());
e1.printStackTrace();
}
}
}
}
「SendExecuteAction」メソッドは別のメソッドによって呼び出され、そのメソッドはその合間に Jason アーキテクチャによって自動的に呼び出されます。問題は、Unity3D アプリケーション内からパッケージを取得しようとすると、一部のパッケージが不足しているように見えることです。実際、Unity から最初のパッケージを取得しますが、他のパッケージは取得しません。別の種類の通信を使用する必要がありますか? すべてのメッセージを非同期で読む必要があります。ネットワーク ストリームからデータを読み取るために使用される C# コードを次に示します。
private IEnumerator CommunicateWithMAS()
{
while (!_ns.DataAvailable)
{
yield return null;
}
byte[] ba = new byte[1000];
AgentServiceThread ast = new AgentServiceThread(_tc, -1, this, ba);
Thread thread = new Thread(new ThreadStart(ast.Communicate));
thread.Start();
StartCoroutine(CommunicateWithMAS());
}
public class AgentServiceThread
{
VCSocketCommScript socketCommScript;
TcpClient client;
int id;
string agentName;
NetworkStream ns;
StreamWriter sw;
StreamReader sr;
string informationString;
string responseString;
FromByteConvertHelper fromBytes;
byte[] ba;
int byteArrayLength = 1000;
public AgentServiceThread(TcpClient client, int id, VCSocketCommScript vcscs, byte[] ba)
{
this.client = client;
this.id = id;
socketCommScript = vcscs;
//this.ba = ba;
fromBytes = new FromByteConvertHelper();
ns = client.GetStream();
}
public void Communicate()
{
byte[] ba = new byte[byteArrayLength];
Debug.Log(ns.DataAvailable);
ns.Read(ba, 0, byteArrayLength);
//Debug.Log(ba.Length);
VCActionRequest action = (VCActionRequest)fromBytes.fromByte(ba, 0, typeof(VCActionRequest));
Debug.Log(action.agentName + " " + action.functor);
socketCommScript.AddAction(action);
ns.Flush();
}
}