I am using an implementation of https://github.com/webrtc for my app. I have a networking stack implemented that uses WebRTC. The issue I am seeing is that when the client exits the app it closes the PeerConnection object, and the server gets a state change from kIceConnectionConnected to kIceConnectionDisconnected which is good and all but I would expect to see kIceConnectionClosed. The problem with the disconnected state is that if your network is spotty then you can intermittently get kIceConnectionDisconnected state which may heal itself afterward. And I don't want to close the connection.
The question is: how do I as a server guarantee that the client has quit the app and that I can tier down the connection on the server side right away?
Edit:
According to https://datatracker.ietf.org/doc/html/draft-ietf-rtcweb-data-channel-13#section-6.7
there should be a channel reset that happens on both sides, how would server knows that it needs to reset the channel?
Related
I am building a WebRTC app where two users are selected at random and then connect to each other to chat. Both clients keep an open WebSocket connection and I am planning to use this to exchange their offers/answers to signal a connection. The case I am trying to account for is when there is a peer that intentionally sends bad configuration information, and also when the peer might spontaneously disconnect in the middle of the signaling exchange.
My solution to the first case is have the server keep state of the exchange, so when the connection is first established I would expect that user A provide an offer and user B have an answer. Is this appropriate? or should this be implemented exclusively client side?
My solution to the second problem feels to me like a hack. What I am trying to do is notify the user that a match has been made and then the user will set a timeout say 20 seconds, if a connection hasn't been made in that amount of time then it should move on...
Are these appropriate solutions? How do you reliably establish a WebRTC when either peer can't be trusted? Should the signaling server be concerned with the state of the exchange?
Sounds like you're more concerned about call set up errors rather than being able to trust the identity of the remote peer. They are two very different problems.
Assuming it is the call set up errors you are concerned about you shouldn't be trying to avoid them you should be trying to make sure your application can handle them. Network connection issues are something that will always crop up and need to be handled.
Setting a timer for the establishment of a WebRTC call to complete is a logical solution. Displaying a warning to the user that the time limit is approaching also seems like a good idea. SIP is a signalling protocol and it has a defined timeout for the completion of a transaction and if it doesn't complete within that time it will generate an error response. You could use the same approach.
We have (Multiple)Clients-(One)Server architecture for poker desktop game. We are using callback Notifications using callback Channels.
But sometimes because of internet connection drops, that particualr client gets disconected from server and that particular's client's WCF channel is also gone to faluted state and his callback Channel which lies in server is also faluted.
Scenario :
That client is playing game, while internet connection drops, that game is stopped, still his game window remains open and when his/her internet connection gets back that client is dropped out from Server, but that player's game window still opens and that player can't do anything as his/her WCF channel is dropped out.
We want to close that particular client's window while he/she is dropped out from server and throwing 'CommunicationObjectAbortedException ' exception.
We can't use previous WCF channel's callback channel as it's in faluted state.
So we have tried to create new callbackChannel in server while dropping using below code :
OperationContext.Current.GetCallbackChannel();
but here Current is showing "NULL" as that player's WCF channel is aborted, so it's throwing an error that "Object reference not set to an instance of object".
So is there any solution to use aborted WCF channel's callback Channel or recover that WCF channel without reinitializing them or to call that client using new channel?
I'd try following:
On server side, when trying to communicate using faulted / aborted chanel - you'll failed.
Catch this failure, and remove its callback from the list (I suppose you manage some callback list).
On client side - when chanel Faulted / ... handled - try to re-open new chanel to server. When this new chenel will be open, on server side place this new callback back to the "valid callbacks" list.
Signaling is not addressed by WebRTC (even if we do have JSEP as a starting point), but from what I understand, it works that way :
client tells the server it's available at X
server holds that information and maps it to an identifier
other client comes and sends an identifier to get connection information from the first client
other client uses it to create it's one connection information and sends it to the server
server sends this to first client
both client can now talk
This is all nice and well, but what happends if a 3rd client arrives ?
You have to redo the whole things. Which suppose the first two clients are STILL connected to the server, waiting for a 3rd client to signal itself, and start the exchanging process again so they can get the 3rd client connection information.
So does it mean you are required to have to sort of permanent link to the server for each client (long polling, websocket, etc) ? If yes, is there a way to do that efficiently ?
Cause I don't see the point of having webRTC if I have to setup nodejs or tornado and make it scales to the number of my users. It doesn't sound very p2pish to me.
Please tell me I missed something.
What about a chat system? Do you really need to keep a permanent link to the server for each client? Of course, because otherwise you have no way of keeping track of a user's status. This "permanent" link can be done different ways: you mentioned WebSocket and long polling, but simple periodic XHR polling works too (although this will affect the UX, depending on the interval).
So view it like a chat system, except that the media stream is P2P for reduced latency. Once a P2P WebRTC connection is established, the server may die and, of course, the P2P connection will be kept between the two clients. What I mean is: both users may always block your server once the P2P connection is established and still be connected together in the wild Internets.
Understand me well: once the P2P connection is established, your server will not be doing any more WebRTC signalling. The connection is only needed to keep track of the statuses.
So it depends on your application. If you want to keep the statuses of users and make them visible to others, then you're in the same situation as a chat system: you need to keep a certain link, somehow, to make sure their statuses are synced. Otherwise, your server exists to connect them together and is not needed afterwards. An example of the latter situation is: a user goes to a webpage, the webpage provides him with a new room URL, the user shares this URL to another peer by another mean, the other peer joins the room, server connects them together (manages WebRTC signalling) and then forgets them. They are now connected until one of them breaks the link. Just like this reference app.
Instead of a central server keeping one connection per client, a mesh network could also be considered, albeit difficult to implement.
Lets say i have an client application on iOS which is connected to a server using a C socket.
I receive and send data on this socket.
Now the user closes the App, so something else (let's say check his mail) and returns to the application.
My (bundle of) question(s):
What to do with the socket connection?
Should you close it and try to reopen the socket when relaunching the application?
Or can i leave the socket open? If so, what happens with the data which is received on the connection?
Other situations to consider are:
I do not know when the user returns to the application.
I do not know if the user stays in the same network.
Thanks
The connection should be closed and the received data saved [if necessary], when the application is about to 'resign active'.
The connection would not be able to run in the background. And you will not receive any data in the background.
When the application resumes from the background reopen the connection and continue.
These methods will help you keep track of your application's state
– applicationWillResignActive:
– applicationDidEnterBackground:
– applicationWillEnterForeground:
I would close the connection and open a new after the app comes to focus. I wrote an app some months ago where the app talked to a radiostation playoutserver to display some information.
- you don't know how long the app stays in background
- you don't know if the user stays within the same network
- you don't know if the user forgets about the still in background living app
...
i would vote for closing the socket connection.
In my specific case: A WCF connection is established, but the only method with "IsInitiating=true" (the login method) is never called. What happens?
In case the connection is closed due to inactivity after some time: Which setting configures this timeout? Is there still a way for a client to keep the connection alive?
Reason for this question: I'm considering the above case as a possible security hole. Imagine many clients connecting to a server without logging in thus preventing other clients from connecting due to bandwidth problems or port shortage or lack of processing power or ...
Am I dreaming, or is this an actual issue?
The WCF client side proxy will close the connection (if open) when it goes out of scope, e.g. when the method it is being used in terminates.
If you're using sessions (but that only kicks in if you actually have indeed established a session - after a method has been called), there's a inactivityTimeout setting in the sessions, both on the client and the server side - the smaller value "wins", so to speak.
If your "concurrentSessions" settings is quite low on your server, this might be an issue - but again, this only kicks in when there is an actual session in place, e.g. at least one method has been called - and in that case, the inactivity timeout on the session will clear out those unused sessions as needed.