Unity3d客户端-Python服务器实时通信

时间:2020-07-08 11:05:27

标签: c# multithreading unity3d parallel-processing

我正在尝试使用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
    }

}
  

0 个答案:

没有答案