Голосовой чат в C#

Тема в разделе "C++ / C# / .NET", создана пользователем Евгенька, 18 мар 2015.

  1. Евгенька

    Евгенька Banned

    Регистр:
    20 фев 2015
    Сообщения:
    153
    Репутация:
    192
    Баллы:
    30
    Пол:
    Мужской
    Голосовой чат в C#
    [​IMG]

    В статье описывается пример элементарного голосового чата. Звук берётся с микрофона при помощи DirectSound и передаётся UDP-пакетами. Перед тем как передать, данные сжимаются войскодером G711. Протокол общения между приёмником и передатчиком выглядит следующим образом:



    PHP:
    Приглашение |
    | --------------------------------> |
    OK |
    | <-------------------------------- |
    | |
    | --------------------------------> |
    поток Аудио |
    | <-------------------------------- |
    Досвидание |
    | --------------------------------> |
    A B

    Структура, содержаща управляющие команды:



    PHP:
    enum Command
    {
    Invite//Сделать вызов.

    Bye//Закончить вызов.

    Busy//Пользователь занят.

    OK//Ответ на приглашение. Значение OK указывает,

    //что вызов принят.

    Null//пустой пакет.

    }

    Когда пользователь делает вызов другого собеседника, приложение посылает команду Invite и ждёт ответа OK. Как только получен ответ OK, начинается приём/передача аудио захваченного с микрофона. Если противоположная сторона отвергает вызов, то отправляется ответ Busy. Для прекращения чата достаточно отправить сообщение Bye. Данный пример приложения ассинхронно принимает/передаёт команды на 1450 порту и синхронно принимает/передаёт звуковые данные 1550 порту. Другими словами, приложение ожидает данных на двух портах: один для управляющих сообщений, а другой для аудио-потока. При запуске, автоматически запускается прослушивание командных сообщений на 1450 порту:

    PHP:
    //использование UDP сокетов

    clientSocket = new Socket(AddressFamily.InterNetwork,
    SocketType.Dgram,
    ProtocolType.Udp);
    EndPoint ourEP = new IPEndPoint(IPAddress.Any1450);

    //Ассинхронное прослушивание управляющих сообщений (Invite, Bye и т.д.) на 1450 порту

    clientSocket.Bind(ourEP);

    //Получение данных разрешается с любого IP-адреса.

    EndPoint remoteEP = (EndPoint)(new IPEndPoint(IPAddress.Any0));
    byteData = new byte[1024];

    //Ассинхронный приём данных.

    clientSocket.BeginReceiveFrom(byteData,
    0byteData.Length,
    SocketFlags.None,
    ref remoteEP,
    new 
    AsyncCallback(OnReceive),
    null);



    После получения сообщения, происходит его обработка. За это отвечает обработчик OnReceive (см. исходник). Для приёма/передачи звука с микрофона запускаются два потока, чтобы можно было синхронно посылать/принимать данные и при этом не блокировать пользовательский интерфейс:



    PHP:
    //использование UDP сокетов

    clientSocket = new Socket(AddressFamily.InterNetwork,
    SocketType.Dgram,
    ProtocolType.Udp);
    EndPoint ourEP = new IPEndPoint(IPAddress.Any1450);

    //Ассинхронное прослушивание управляющих сообщений (Invite, Bye и т.д.) на 1450 порту

    clientSocket.Bind(ourEP);

    //Получение данных разрешается с любого IP-адреса.

    EndPoint remoteEP = (EndPoint)(new IPEndPoint(IPAddress.Any0));
    byteData = new byte[1024];

    //Ассинхронный приём данных.

    clientSocket.BeginReceiveFrom(byteData,
    0byteData.Length,
    SocketFlags.None,
    ref remoteEP,
    new 
    AsyncCallback(OnReceive),
    null);

    Методы Send и Receive можно посмотреть в прилагаемом ниже исходнике; разобраться с ними не составит труда.
    Сам исходник : Скачать исходник - 21 кб