Ant Media Server WebRTC connection in Unity - unity3d

I've been following this tutorial : https://antmedia.io/webrtc-streaming-in-unity/ in order to try and receive a WebRTC stream into unity.
I've downloaded the https://github.com/ant-media/WebRTC-Unity-SDK WebRTC unity SDK.
I created a Ant Server on Linode and broadcast into it using OBS.
The unity sample does not look like the one in the tutorial/
I opened the AMSStreaming scene In Unity, and modified the url in the AMSStreaming script to point to my server : "ws://my_server_ip:5080/WebRTCApp/websocket"
and provided the WebRTCClient with the correct stream id and url.
I left the stun server to the default stun server address : stun:stun.l.google.com:19302
Running the sample, I set the comboBox to "Play" and click "Start".
The connection works fine and
else if(mode == MODE_PLAY) {
webRTClient.Play();
gets executed.
However nothing else happens, no RTCTrackEvent are received.
I have also placed a breakpoint in the CreatePeerConnection() Method :
localPC.OnIceConnectionChange = state => {
switch (state)
{
case RTCIceConnectionState.Connected:
//PeerConnected();
//break;
case RTCIceConnectionState.New:
case RTCIceConnectionState.Checking:
case RTCIceConnectionState.Closed:
case RTCIceConnectionState.Completed:
case RTCIceConnectionState.Disconnected:
case RTCIceConnectionState.Failed:
case RTCIceConnectionState.Max:
Debug.Log("IceConnectionState: "+state);
break;
default:
throw new ArgumentOutOfRangeException(nameof(state), state, null);
};
};
That never gets hit, so the ICEConnectionChange never changes.
Could that be the problem ?
How can I move forward debugging this ?
Thanks

Related

Set up a connection that times out for Apache Geode Client

I have a windows desktop application on .NET Framework that a user can interact with. There is a "connect" button that sets up Apache Geode client connection to Geode Server.
When Geode Server is down (Locator - there is only 1) the desktop application hangs indefinitely and needs to be forcefully closed.
This is how we connenect to the server and hangs on last line indefinitely:
PoolFactory poolFactory = _cache.GetPoolManager()
.CreateFactory()
.SetSubscriptionEnabled(true)
.AddLocator(_host, _port);
return poolFactory.Create(_serviceName);
I would like to add a time-out period for this method to return or throw exceptions or anything.
Alternatively, I've wrapped it on a different kind of timer outside of this to just return, but when trying to run the above code again (to try to connect the application again) the pool is still trying to connect.
I have tried to destroy it like this:
//destroy the pool
var poolManager = _cache.GetPoolManager();
if (poolManager != null)
{
var pool = poolManager.Find(_serviceName);
if (pool != null && pool.Destroyed == false)
pool.Destroy();
}
But then the pool.Destroy(); hangs indefinateley
How can I have a mechanism to attempt to connect to the Geode server, return if not connected within 10 seconds, then leave and are able to try to connect again using the same cache?
Note above was trying to re-use the same cache, probably setting cache to null and trying all over again would work, but I am looking for a more correct way to do it.
Depending on what version of .NET native client you are using. There is a property in 10.x connect-timeout that should work. Additionally, you can wrap your connection code under try{...}catch{} block and handle an exception for Apache.Geode.Client.TimeoutException and/or ": No locators available".
Example:
var _cache = new CacheFactory()
.Set("log-level", "config")
.Set("log-file", "C:\temp\test.log")
.Set("connect-timeout", "26000ms")
.Create();
_cache.GetPoolManager()
.CreateFactory()
.SetSubscriptionEnabled(true)
.AddLocator(hostname-or-ip", port-number)
.Create("TestPool");

Formulate correct scenario phrase

I would like to know, if the following Gherkin phrase correspond to BDD rules:
final class KafkaSpec extends BddSpec {
feature("Kafka distribution to SAP server via websocket") {
scenario("Kafka consumer does not receive messages from Kafka server") {
Given("Kafka server is NOT active")
When("consumer client get started")
val ex = SenderActor.run
Then("print message `Failed to connect to Kafka`")
ex.failed map { ex =>
assertThrows[ConnectException](ex)
}
}
scenario("Kafka consumer receives messages from Kafka server") {
Given("Kafka server is ACTIVE")
When("consumer client get started")
Then("print message `Successfully connected to Kafka`")
succeed
}
}
}
Do I use the right tense? Do I use the Given-When-Then correctly?
The Givens (contexts) are fine; we normally use either continuous present or past tense for those:
Given the kafka server is active <-- continuous present
Given the kafka server was started <-- past tense
For the Whens (events), it's better if you can use an active voice. Active voice starts with who did it. Who started the server? (I've corrected the English a bit here too.)
When the consumer client was started <-- passive voice
When our consumer starts their client <-- active voice
For the Thens (outcomes), I really like the word "should". It encourages people to question it; should it really happen? Now? In this release? Is there any context for which this shouldn't happen or something different should happen? Should it still happen, or has this scenario changed?
Then the consumer interface should print the message, `Successfully connected to Kafka`.
One other thing though: the detail in that last step feels a bit too much to me. If the message changed, you'd have to change it everywhere. Instead I keep that in the code (you can abstract the step out) and would say something like:
Then the interface should tell the consumer that the connection was successful.
This is something we usually call "declarative over imperative". It's also OK to have the passive voice here:
Then the consumer should be told that the connection was successful.
Using the word "should" also helps differentiate between the outcomes of one scenario and the givens of another; often these overlap with an outcome forming the context for another scenario:
Given Priscilla has an account
When she enters her username and password correctly
Then she should be on her home page.
Given Priscilla is on her home page...
I wrote more about tenses and language of BDD here, where you'll also find tons of other resources for new BDDers under the BDD category.

Play ws scala server hangs up on request after 120seconds - which options to use?

I am pretty sure that this is a config problem, so I'll post my code and the relevant application.conf options of my play app.
I have a play server that needs to interact with another server "B" (basically multi-file upload to B). The interaction happens inside an async -Action which should result in an OK with B's response on the upload. This is the reduced code:
def authenticateAndUpload( url: String) = Action.async( parse.multipartFormData) { implicit request =>
val form = authForm.bindFromRequest.get
val (user, pass) = (form.user, form.pass)
//the whole following interaction with the other server happens in a future, i.e. login returns a Future[Option[WSCookie]] which is then used
login(user, pass, url).flatMap {
case Some(cookie) => //use the cookie to upload the files and collect the result, i.e. server responses
//this may take a few minutes and happens in yet another future, which eventually produces the result
result.map(cc => Ok(s"The server under url $url responded with $cc"))
case None =>
Future.successful(Forbidden(s"Unable to log into $url, please go back and try again with other credentials."))
}
}
I am pretty sure that the code itself works since I can see my server log which nicely prints B's responses every few seconds and proceeds until everything is correctly uploaded. The only problem is that the browser hangs up with a server overloaded message after 120s which should be a play default value - but for which config parameter?
I tried to get rid of it by setting every play.server.http. timeout option I could get my hands on and even decided to use play.ws, specific akka, and other options of which I am quite sure that they are not necessary... however the problem remains, here is my current application.config part:
ws.timeout.idle="3600s"
ws.timeout.request ="3600s"
ws.timeout.response="3600s"
play.ws.timeout.idle="3600s"
play.ws.timeout.request="3600s"
play.ws.timeout.response="3600s"
play.server.http.connectionTimeout="3600s"
play.server.http.idleTimeout="3600s"
play.server.http.requestTimeout="3600s"
play.server.http.responseTimeout="3600s"
play.server.http.keepAlive="true"
akka.http.host-connection-pool.idle-timeout="3600s"
akka.http.host-connection-pool.client.idle-timeout= "3600s"
The browser hang up happened both on Safari and Chrome, where Chrome additionally started a second communication with B after about 120 seconds - also both of these communications succeeded and produced the expected logs, only the browsers had both hang up.
I am using Scala 2.12.2 with play 2.6.2 in an SBT environment, the server is under development, pre-compiled but then started via run - I read that it may not pick up the application.conf options - but it did on some file size customizing. Can someone tell me the correct config options or my mistake on the run process?

socket.io properly disconnect a socket from unity side

I am trying to properly close a socket of socket.io that got open from unity side. My problem is that, even though I expect one log information from unity side (server disconnected) and one in server side, I get my "bye" message, multiples of times, around 10 times, from server side (unity side publishes only 1 time, as expected). Could you please tell me how could I prevent this overhead, and why the repetition is happening?
On unity side, using a free scoket.io plugin, I have the code:
void Start () {
socket = GetComponent<SocketIOComponent> ();
socket.On ("open", OnOpen);
socket.On ("disconnect", OnDisconnect);
}
void OnDisconnect(SocketIOEvent e){
Debug.Log ("server disconnected!");
socket.Close ();
}
in server side, my test code is:
io.on('connection', function(socket) {
console.log('bye...');
socket.disconnect(true);
});

how to display a new created object on both devices in Unity networking?

I am working on a network game with Unity3D network. I am new to network programming.
Let's say I created objects and attached them to the player (either on server or client). I need to keep displaying those objects on another device. I've seen many materials, but I haven't found a solution yet.
It seems NetworkServer.Spawn is a way to do it. Is that right and any other better way? Give some advice to this novice^^ Thanks.
If you're using NetworkServer.Spawn you need to register your prefab in your NetworkManager.
If you're not expecting anyone new to join your server you can also use Command and ClientRPC that will spawn this prefab and parent it to correct game object on every client.
Only server/host can spawn network-synched GameObjects.
// put this component on a prefab you wish to spawn
class MyNetworkedObject : NetworkBehaviour
{
[SyncVar]
public int myHealth;
void Start()
{
Debug.Log("My health is: " + myHealth);
}
}
// put this component on an empty GameObject somewhere in the scene and check "Server Only" on its NetworkIdentity
class MySpawner : NetworkBehaviour
{
public MyNetworkedObject myPrefab;
void OnValidate()
{
if (GetComponent<NetworkIdentity>().serverOnly == false)
Debug.LogWarning("This component wants NetworkIdentity to have \"Server Only\" checked (for educational purposes, not an actual requirement).");
}
public void SpawnObject(int withHealth)
{
if (!isServer)
throw new Exception("Only server may call this! It wouldn't have any effect on client.");
MyNetworkedObject newObject = Instantiate(myPrefab);
// setup newObject here, before you spawn it
newObject.myHealth = withHealth;
NetworkServer.Spawn(newObject.gameObject);
}
}
As Fiffe already mentioned, the prefab must be registered inside your NetworkManager for it to be spawnable. Also, all networked objects must have a NetworkIdentity component.
Once the object is spawned by the server, server will tell all connected clients to spawn the object with current values of any SyncVars, and also on any clients that might connect later. If SyncVars change on the server, server will tell all connected clients to change the value accordingly.
If you want clients to invoke the spawning of an object, the easiest way is to go with Local Authority:
// put this component on the player prefab that you already assigned to NetworkManager.PlayerPrefab
class MyNetworkedPlayerObject : NetworkBehaviour
{
void OnValidate()
{
if (GetComponent<NetworkIdentity>().localPlayerAuthority == false)
Debug.LogWarning("This component requires NetworkIdentity to have \"Local Player Authority\" checked.");
}
public void RequestSpawnObject(int withHealth)
{
if (!hasAuthority)
throw new Exception("Only the player owned by this client may call me.");
// the following call will magically execute on the server, even though it was called on the client
CmdSpawnObject(withHealth);
}
[Command]
private void CmdSpawnObject(int withHealth)
{
// this code will always run on the server
FindObjectOfType<MySpawner>().SpawnObject(withHealth);
}
}
Each client can have one or more networked objects with Local Player Authority. Each networked object is either owned by server, or by exactly one client that has Local Player Authority for that object. Client may invoke Commands only on objects that that client has Local Player Authority on. Commands are invoked by the client, but executed on the server. This execution will happen asynchronously, client can not know when the server will execute it. Thus, Commands can have parameters, but no return value.
Also:
If you want all clients to execute a method on a networked object, server can invoke [ClientRPC] methods on any networked object, which will then execute on the clients. If a client connects later, it will not invoke rpc calls that happened before the client connected.
Even clients with Local Player Authority can not change SyncVars. If they do, server and other clients will not receive the changes. Only server can change SyncVars and have it synchronized to the clients
Transform is a special case. Objects can have a NetworkTransform component which allows owning client (or server) to control the position and rotation of that object and have it synched to server and other clients. Same with NetworkAnimator.
If you want to decide at runtime whether the server or the client have authority over an object, you must have a prefab for either case, one with "Local Player Authority" checked, one without. Server can never be owner of an object that has "Local Player Authority" checked (but local client on a host can).
Clients can send messages to the server and vice versa.
I hope this gives you a short overview.