我正在尝试使用Unity3D和python创建客户端服务器应用程序。我正在尝试将大量数据从服务器实时发送到客户端。为了做到这一点,我将要接收的数据分成较小的块,以便序列化/反序列化更快,因此基于数据的统一对象更新也更快。
我这样处理问题:
我打开5个套接字,每个套接字都尝试根据标识符来处理请求
在客户端上,我使用parallel.foreach发送五个标识符,然后并行接收。
问题是client.Receive
会在没有数据要接收时阻塞。我试图设置一个超时时间,但这并没有帮助。
对于收到的包裹,数据长度也是可变的。
Python服务器实现与此相似,但是我认为Is it possible to run multiple asyncio in the same time in python?
并不相关。Socket class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using System;
using System.IO;
public class SocketConnector
{
public string ip = "127.0.0.1";
public int port = 60000;
private Socket client;
[SerializeField]
private int dataOut;
private byte[] dataIn; //debugging
public SocketConnector() { }
public void establishConnection(int port)
{
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(ip, port);
}
public byte[] ServerRequest(int dataOut)
{
//print("request");
this.dataOut = dataOut; //debugging
this.dataIn = SendAndReceive(dataOut); //debugging
return this.dataIn;
}
private byte[] SendAndReceive(int dataOut)
{
byte[] z = new byte[1024 * 1024 * 1500];
try
{
byte[] intBytes = BitConverter.GetBytes(dataOut);
client.Send(intBytes);
client.ReceiveTimeout = 2000;
//allocate and receive bytes
byte[] bytes = new byte[1024 * 1024 * 1500];
Array.Clear(bytes, 0, bytes.Length);
int lenght = 1, byteIndex = 0;
lenght = client.Receive(bytes); // is blocking here cos no data is received sometime
Buffer.BlockCopy(bytes, 0, z, byteIndex, lenght);
byteIndex += lenght;
Array.Resize(ref z, byteIndex);
Debug.Log("request received");
}
catch (Exception e)
{
Debug.Log("smth happened");
}
client.Close();
return z;
}
}
Main class:
...
void Start()
{
ThreadCompoennt threadComponent = new ThreadComponent(socketConnector, this, featureMapCreator);
threadComponent.init();
}
...
Thread component:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
using System.Linq;
using System.Threading.Tasks;
using MessagePack;
using System;
public class ThreadComponent
{
Thread thread;
SocketConnector socketConnector;
Main main;
Dictionary<string, Dictionary<string, ushort[][]>> feature;
StructHelper structHelper;
byte[] z;
public ThreadComponent(SocketConnector socketConnector, Main main, FeatureMapCreator featureMapCreator)
{
this.featureMapCreator = featureMapCreator;
this.socketConnector = socketConnector;
this.main = main;
}
public void init()
{
thread = new System.Threading.Thread(doLogic);
thread.IsBackground = true;
thread.Start();
}
void doLogic()
{
List<int> integerList = Enumerable.Range(1, 5).ToList();
while (true)
{
Thread.Sleep(2000);
Parallel.ForEach(integerList, i =>
{
socketConnector.establishConnection(60000 + i);
doLogicGetData(i, socketConnector);
});
}
}
void doLogicGetData(int batchIdentifier, SocketConnector socketConnector)
{
z = socketConnector.ServerRequest(batchIdentifier);
if (z.Length != 0)
{
this.feature = MessagePackSerializer.Deserialize<Dictionary<string, Dictionary<string,ushort[][]>>>(z);
..... do update based on batch identifier
}
}