Unity C # Сокет обратного вызова, который запускает журналы событий на консоли, но не может изменить свойства игровых объектов - PullRequest
0 голосов
/ 19 октября 2019

Я написал следующий класс сокетов для обработки связи между клиентом и сервером, класс просто подключается к серверу и вызывает событие при получении сообщения от сервера.

public class socketsFunctionality : MonoBehaviour
{
    Socket socket;
    public const int BufferSize = 16384; 
    public byte[] buffer = new byte[BufferSize];
    public delegate void OnAssignCardsDelegate(listOfCards cards);
    public OnAssignCardsDelegate OnAssignCards;

    void Start()
    {
        IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("192.168.0.2"), 80);

        Socket client = new Socket(AddressFamily.InterNetwork,
            SocketType.Stream, ProtocolType.Tcp);

        client.BeginConnect(remoteEP,
            new AsyncCallback(ConnectCallback), client);
    }
    private void ConnectCallback(IAsyncResult ar)
    {

        socket = (Socket)ar.AsyncState;
        socket.EndConnect(ar);
        socket.BeginReceive(buffer, 0, BufferSize, 0,
       new AsyncCallback(CardsReceived), socket);
    }

    private void CardsReceived(IAsyncResult ar)
    {
        Socket s = (Socket)ar.AsyncState;
        int bytesRead = s.EndReceive(ar);
        OnAssignCards.Invoke(new listOfCards());
    }

}

Изатем в другом классе я подписываюсь на это событие, и оно срабатывает успешно, и я могу записать в консоль, но по какой-то причине не могу обновить пользовательский интерфейс игры.

public class tableScript : MonoBehaviour, IDropHandler
{
    void Start()
    {
        socketFunctionality.GetComponent<socketsFunctinality>().OnAssignCards += CardsReceived;
    }

    public void CardsReceived(listOfCards cards)
    {
        Debug.Log("triggered"); //outputs triggered
        gameObject.transform.scale = new Vector3(100f,100f,100f); // nothing happenes
    }
}

Однако, если яПереместите OnAssignCards.Invoke в функцию Start класса socketsFunctionality, код работает правильно.

Я думаю, что это проблема с многопоточностью, но я не мог ее понять.

1 Ответ

0 голосов
/ 19 октября 2019

Поскольку вы используете Async Receiver, это может быть ожидаемым результатом, которого вы страдаете.

Я предложил вам поставить в очередь все полученные сообщения с блокировкой, затем удалить их из очереди и обработать в цикле обновления. Или используйте цикл while в сопрограмме для проверки любого нового полученного сообщения. Потому что вызывающие события должны вызываться в главном потоке.

...