Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: VoIp System where server passes clients speech to every other client.  (Read 13032 times)

0 Members and 1 Guest are viewing this topic.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: VoIp System where server passes clients speech to every other client.
« Reply #15 on: June 26, 2018, 08:31:22 am »
Yes, that looks correct.
Laurent Gomila - SFML developer

Deliciouscookie

  • Newbie
  • *
  • Posts: 14
    • View Profile
    • Email
Re: VoIp System where server passes clients speech to every other client.
« Reply #16 on: June 26, 2018, 08:16:43 pm »
Yes, that looks correct.
So if client is connected to Server. Do I need to make some forever running loop in clients also? And If client is connected, does it receive packages automatically if I use something like this:

Quote
char data[100];
std::size_t received;

// TCP socket:
if (socket.receive(data, 100, received) != sf::Socket::Done)
{
    // error...
}
std::cout << "Received " << received << " bytes" << std::endl;

Or what kind of procedures I need to set in client side, so it would get the packed data from server? I am lost because server created the NetworkAudioStream from SoundStream, so do I need to create same stream to client also or how does it work in Server--> Client side? .
« Last Edit: June 26, 2018, 08:24:53 pm by Deliciouscookie »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: VoIp System where server passes clients speech to every other client.
« Reply #17 on: June 27, 2018, 07:55:55 am »
You should go step by step. Do simple networking first, don't try to do everything at the same time. We could help you write your program on this forum, but you wouldn't learn much in the end. Read the tutorials, write simple client / server programs, test things by yourself, etc. :)
Laurent Gomila - SFML developer

Deliciouscookie

  • Newbie
  • *
  • Posts: 14
    • View Profile
    • Email
Re: VoIp System where server passes clients speech to every other client.
« Reply #18 on: June 28, 2018, 10:13:54 pm »
--- Nothing Yet. Something happening.

Edit: Yesss. It's working finally! Phew, I thought I never see end of it. Now it's time to take deep breath, import this whole system as Unreal Engine Plugin, test this for good and then starting to figure out how can I detect when people is speaking and just then send the audio over network. Also need to figure out how I can pass the data of the person that is speaking to Unreal so the avatar can me marked as speaking avatar.
« Last Edit: June 29, 2018, 10:31:51 pm by Deliciouscookie »

Deliciouscookie

  • Newbie
  • *
  • Posts: 14
    • View Profile
    • Email
Re: VoIp System where server passes clients speech to every other client.
« Reply #19 on: July 03, 2018, 05:18:03 pm »
One wall came up again and not been able to solve it.

I have two classes.
(click to show/hide)


As you can see this class is responsible for listening clients and passing sound packets to everybody. Now hear me out, because this sounds so strange to me and I think there is some underlying thing that I don't know. I have problem by having this class to go full circle and closing.

I can start the Server in my project and Clients can join to it. If client leaves and sends the endOfStream my server successfully completes and shuts down. All good so far.

Problem is that I want to shutdown server in my own computer. Logically I could simply change the Canrun to false and program would shutdown in next loop but that ain't happening. Program gets stuck to somewhere. I even created custom class and send the same endOfStream message to server locally, but that ain't helping, the class just wont complete. I then tried to use the example VoIP in same computer where the server is running by connecting to localhost. After sending endOfStream, the server shuts down propertly again.

Now comes the strange part. While I was debugging, I removed EVERYTHING from the receiveLoop() function and still the class wont complete. The only way I get it to complete is to connect to it from different program and send the end message. I have been fighting this for so long but cannot figure out what is causing this.

My .CPP file here:
This is my current attempt. But like I said, I had a system, that spawn a temporaly class that sends the EndOfStream Packet to server from the same computer, but that didn't help. I can see that server receives the packet. and says UE_LOG(LogTemp, Warning, TEXT("Audio Stream successfully finished")); but the program wont end. Also, notice that I need to run this program in backgroundthread in Unrea or the mainthread freezes. Not sure if that has something to do with it.

Quote
(click to show/hide)


I'm all out of hope here. What bugs me the most is WHY it's working as it supposed to when the data is send over the network, but not locally. And why the program doesn't complete, even if the whole function is empty. Please help.
« Last Edit: July 03, 2018, 05:37:19 pm by eXpl0it3r »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: VoIp System where server passes clients speech to every other client.
« Reply #20 on: July 03, 2018, 05:41:53 pm »
You're using blocking sockets, so the receive calls will block until they receive data. Which also means that your function gets stuck waiting for data.

Maybe there are more issues that I missed by glancing over it.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Deliciouscookie

  • Newbie
  • *
  • Posts: 14
    • View Profile
    • Email
Re: VoIp System where server passes clients speech to every other client.
« Reply #21 on: July 03, 2018, 07:49:41 pm »
You're using blocking sockets, so the receive calls will block until they receive data. Which also means that your function gets stuck waiting for data.

Maybe there are more issues that I missed by glancing over it.

I think I found out the culprit. It is because stop() function won't work if the EndStream data won't come over network. I tested this by doing this:

Quote
                        if (id == endOfStream)
                        {
                           // End of stream reached: we stop receiving audio data
                           //   std::cout << "Audio data has been 100% received!" << std::endl;
                           stop();
                           Canrun = false;
                           UE_LOG(LogTemp, Warning, TEXT("Audio Stream successfully finished"));
                        }

If I create server and connect client through other program and then send endOfStream id, program goes pass the stop() and I get the LOG printing. If I create client and connect it through the visual studio code and then send endOfStream id, I never get the LOG printing, so program halts to stop and never goes pass it. Also, If I remove all the code and not run the stop(), the program never ends. The problem was never that I won't getting out of the loop. Problem is that I cannot run the stop() command for some reason.

So, question is, why the stop() won't run for me.


Deliciouscookie

  • Newbie
  • *
  • Posts: 14
    • View Profile
    • Email
Re: VoIp System where server passes clients speech to every other client.
« Reply #22 on: July 03, 2018, 08:42:55 pm »
You're using blocking sockets, so the receive calls will block until they receive data. Which also means that your function gets stuck waiting for data.

Maybe there are more issues that I missed by glancing over it.

I think I found out the culprit. It is because stop() function won't work if the EndStream data won't come over network. I tested this by doing this:

Quote
                        if (id == endOfStream)
                        {
                           // End of stream reached: we stop receiving audio data
                           //   std::cout << "Audio data has been 100% received!" << std::endl;
                           stop();
                           Canrun = false;
                           UE_LOG(LogTemp, Warning, TEXT("Audio Stream successfully finished"));
                        }

If I create server and connect client through other program and then send endOfStream id, program goes pass the stop() and I get the LOG printing. If I create client and connect it through the visual studio code and then send endOfStream id, I never get the LOG printing, so program halts to stop and never goes pass it. Also, If I remove all the code and not run the stop(), the program never ends. The problem was never that I won't getting out of the loop. Problem is that I cannot run the stop() command for some reason.

So, question is, why the stop() won't run for me.

Got it working. Problem was when I spawned the class that sole purpose was to send the endStream message, it was destroyed too soon. So I added a little timer so the buffer get some data and then the endStream message goes through and everything closes nicely. Not best way i'm sure, but atleast now it's working without constant crashes

Quote
   FTimerDelegate TimerCallback;
   TimerCallback.BindLambda([&]
   {
      WaitLittle = false;
   });

   FTimerHandle Handle;
   World->GetTimerManager().SetTimer(Handle, TimerCallback, 0.5f, false);

   LambdaServer = FLambdaRunnable::RunLambdaOnBackGroundThread([&]()
   {
      // Build an audio stream to play sound data as it is received through the network
      Disconnecter Disconnect("localhost", 2435);
      Disconnect.start();
      while (WaitLittle);
   });

Deliciouscookie

  • Newbie
  • *
  • Posts: 14
    • View Profile
    • Email
Re: VoIp System where server passes clients speech to every other client.
« Reply #23 on: July 07, 2018, 11:13:51 pm »
You're using blocking sockets, so the receive calls will block until they receive data. Which also means that your function gets stuck waiting for data.

Maybe there are more issues that I missed by glancing over it.

I think I found out the culprit. It is because stop() function won't work if the EndStream data won't come over network. I tested this by doing this:

Quote
                        if (id == endOfStream)
                        {
                           // End of stream reached: we stop receiving audio data
                           //   std::cout << "Audio data has been 100% received!" << std::endl;
                           stop();
                           Canrun = false;
                           UE_LOG(LogTemp, Warning, TEXT("Audio Stream successfully finished"));
                        }

If I create server and connect client through other program and then send endOfStream id, program goes pass the stop() and I get the LOG printing. If I create client and connect it through the visual studio code and then send endOfStream id, I never get the LOG printing, so program halts to stop and never goes pass it. Also, If I remove all the code and not run the stop(), the program never ends. The problem was never that I won't getting out of the loop. Problem is that I cannot run the stop() command for some reason.

So, question is, why the stop() won't run for me.

Got it working. Problem was when I spawned the class that sole purpose was to send the endStream message, it was destroyed too soon. So I added a little timer so the buffer get some data and then the endStream message goes through and everything closes nicely. Not best way i'm sure, but atleast now it's working without constant crashes

Quote
   FTimerDelegate TimerCallback;
   TimerCallback.BindLambda([&]
   {
      WaitLittle = false;
   });

   FTimerHandle Handle;
   World->GetTimerManager().SetTimer(Handle, TimerCallback, 0.5f, false);

   LambdaServer = FLambdaRunnable::RunLambdaOnBackGroundThread([&]()
   {
      // Build an audio stream to play sound data as it is received through the network
      Disconnecter Disconnect("localhost", 2435);
      Disconnect.start();
      while (WaitLittle);
   });

I come here again, asking for your guidance. This time, I created a video that demonstrates the problem I am having. The way I previously did the disconnecting(creating new client, connect it to server and send EndofStream) is too hacky way to do it, so I rather won't do it like that. If you have time to watch the video and give your thoughts about it, I would be very grateful. If you have any questions about the video, please let me know.

Here is the youtube link to video:


edit: My guess is that it has something to do with the background thread running in SFML that won't shutdown properly.

« Last Edit: July 07, 2018, 11:15:38 pm by Deliciouscookie »