Как получить данные с сервера? - PullRequest
0 голосов
/ 08 января 2019

Я пишу приложение для чата с C # Windows Froms. Моя проблема в том, что мой сервер может отправлять сообщения каждому подключенному клиенту, но только клиент, отправивший сообщение, может получить ответ. Я попытался создать такую ​​функцию, как ReceiveLoop () с бесконечным циклом внутри, или добавить функцию таймера и вызывать функцию Receive () для каждого тика, но обе не увенчались успехом из-за сбоя приложения. Как получить данные в режиме реального времени? Я прилагаю код приложения моего клиента.

public partial class Form1 : Form
{
    private string name;
    private Socket _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    private void Namebt_Click(object sender, EventArgs e)
    {
        if (!Test(Nametb.Text)) Nametb.Text = "Nie wpisano nazwy!";
        else
        {
            name = Nametb.Text;
            Nametb.Clear();
            Nametb.Enabled = false;
            Namebt.Enabled = false;
            Messageslb.Enabled = true;
            timer1.Start();
            LoopConnect();
        }
    }

    private void LoopConnect()
    {
        int attempts = 0;
        while (!_clientSocket.Connected)
        {
            try
            {
                attempts++;
                _clientSocket.Connect(IPAddress.Loopback, 100);

            }
            catch (SocketException)
            {
                Messageslb.Items.Clear();
                Messageslb.Items.Add("Connection attempts: " + attempts.ToString());
                Messageslb.Refresh();
            }
        }
        Messageslb.Items.Add("Connected!");
        Messageslb.Refresh();
        Messagetb.Enabled = true;
        Sendbt.Enabled = true;
    }

    private bool Test(string text)
    {
        if (text != "") return true;
        return false;
    }

    private void Sendbt_Click(object sender, EventArgs e)
    {
        if (!Test(Messagetb.Text)) Messagetb.Text = "Nie wpisano zadnej wiadomosci!";
        else
        {
            Send();
        }
    }
    private void Receive()
    {
        if(_clientSocket.ReceiveBufferSize > 0)
        {
            byte[] receivedBuffer = new byte[1024];
            int rec = _clientSocket.Receive(receivedBuffer);
            byte[] data = new byte[rec];
            Array.Copy(receivedBuffer, data, rec);
            Messageslb.Items.Add(Encoding.ASCII.GetString(data));
        }         
    }

    private void Send()
    {
        string message = "[" + name + "]: " + Messagetb.Text;
        Messagetb.Clear();
        byte[] buffer = Encoding.ASCII.GetBytes(message);
        _clientSocket.Send(buffer);
        Receive();
    }

    private void Nametb_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Return) Namebt_Click(sender, e);
    }

    private void Messagetb_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Return) Sendbt_Click(sender, e);
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        Receive();
    }
}

1 Ответ

0 голосов
/ 08 января 2019

Вам нужно запустить метод приема для отдельной задачи.

_clientSocket.Receive(receivedBuffer);

должно быть:

private Task _receiving;
private void Receive()
{
  if(_clientSocket.ReceiveBufferSize > 0)
    {

    if(_receiving == null || _receiving.IsCompleted)
     _receiving = Task.Run(() => 
     {
        byte[] receivedBuffer = new byte[1024];
        int rec = _clientSocket.Receive(receivedBuffer);
        byte[] data = new byte[rec];
        Array.Copy(receivedBuffer, data, rec);
        Messageslb.Items.Add(Encoding.ASCII.GetString(data)); 
     });

 }
}

В противном случае clientSocket.Receive повесит вашу программу.

Вы захотите убедиться, что Messageslb является потокобезопасным, но это потребует дальнейших исследований.

Если вы ищете связь в режиме реального времени, загляните в RTC Client для C # https://msdn.microsoft.com/en-us/library/ms946701.aspx. В противном случае я очень рекомендую Socket.IO, поскольку он действительно прост в использовании и настраивается с чрезвычайно быстрым rtc! https://socket.io/get-started/chat

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...