I'm trying to set up a client-server architecture. I have one GKSession configured as a server, and two others as clients.
When either client uses the sendData:toAllPeers:WithDataMode:error method, it sends it not only to the server but to the other client.
I guess I could use the display name to exclude clients, so client data only goes to the server, but I'm not quite following why this is happening.
My server explicitly accepts a connection, via acceptConnectionFromPeer:error: But my client isn't accepting anything from anybody, it seems to be just silently finding the other client.
Should this be happening? I understand in a peer-peer setup you'd want peers to just find others; but in client-server, this seems a little weird.
Any clarification or advice would be greatly appreciated.
While a client cannot explicitly connect to another client, but the method sendData:toPeers:withDataMode:error: should allows you to send data directly from one client to another given that you have the correct peerId.
Related
I am experimenting with using Reactive Extensions to create a Windows Service.
Essentially what I want is for the Observer to sit on the server, the clients able to create observables and have them pushed to the server, the server informing the client of the progress of the job (not sure how to do this or what mechanism to use to do it), and then when it's done, having the server send the client the return code and output of the program it called. Can this be done? Is it the best way to do what I'm trying to do? If you need any more information, what would you need to know to help me?
This seems back to front. Generally clients know about servers (how to find then and connect). In contrast the Observer pattern (and therefore Rx) is about allowing something to callback to another observer that is does not know about.
In your case I think you simply want to have clients call methods on a server. Potentially these are bound to a single connection/session. The client however maybe an observer of the progress from the server and the final result.
See the Reactive Trader project by the team at Adaptive to see a .NET client server app using Rx.
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.
does someone know if it possible to use one WCF Data Service as data source of another WCF Data Service? If so, how?
So the short answer is yes. Actually I have consumed one WCF service in another (HttpBinding coming to a service on computer, then that service had a NamedPipesBinding service to communicate with multiple desktop apps, but it did some data transformation in the middle). That would not be an issue at all, you would set up a proxy/client just like you would in a desktop client, and handle everything in your new service as if it was just passing information along, you could even create a shared library for the DataContracts and such.
HOWEVER I would not suggest the leapfrog method in your implementation. Depending on how many customers you are potentially opening the door too, you may be introducing a bottlekneck, if you have a singleton service, or overload your existing service in the case of many connections from the new one. Since you have a SQL server, why would you not have a WCF service on your web/app server (public) that connected to it and provided the data you need? I'm only thinking this because your situation can become exponentially complicated when you start trying to pass credentials for authentication and authorization between the two, depending on your security settings. Another thing to consider is the complexity in debugging this new service and the old one, and a client at the same time, as if it wasn't a pain just to do server and client, since you are opening it to a public facing port, there are different things to set up, and debugging everything on the same machine is not the same as a public facing application server.
Sorry if this goes against what you were hoping to hear. I'm just saying that it is possible, but not suggested (at least by me) in your particular case.
I am facing a situation regarding hosting WCF on Session Instancing mode.I am encapsulating the actual situation and proposing an example to replicate it...as below.
The service to be hosted is "MyService". I am using windows service to host it..with http endpoint.
It will need to support 500 concurrent sessions.(Singleton & Percall cannot be done because the Contract is Workflow based...Login...Function1,Function2,Logout..)
I have 4 Servers each with a hardware capability of supporting 200 concurrent sessions.
So I configured the service on One server as a Router(ServiceHost S = new ServiceHost(RouterService)) with hosting path such as "http://myserver/MyService". I have set a simple load balancing mechanism and applied the Router table to redirect incoming requests to other three servers where the actual service copies are hosted...("http://myserver/MyService1","http://myserver/MyService2","http://myserver/MyService3")
It is still not working...As soon as hits go above 200...communication error starts...I suppose because when 500 concurrent calls are made, then the Router(capability 200) is also required to stay connected to the Client along with the Actual Service Server...(in Session Call mode)..Is my thinking correct??
My question is...
1) Is my approach correct or flawed from concept...Should I ask the Hardware team to set up NLB...
2) Should we redesign the contract specifically to ensure that the requests can somehow be made PerCall...
3) Someone suggested that such systems should be hosted on cloud (Windows Azure)...will need to look at costs involved...but is it correct...
4) What are the best practicies involved while hosting WCF to handle Session Based Calls.
I understand that my question is complex and there would not be one "Correct" answer...but any help and insight will be really appreciated.
Thanks
"Should I ask the Hardware team to set up NLB..." as per you & "Sticky IP cluster" by Shiraz are the closest one can get to host the given scnerio.
The thing is that WCF sessions are transport based.hence we cannot store these "sessions" on a state server/db like a traditional aspnet.
WCF4.0 has come up with new bindings such as NetTcpContextBinding, BasicHttpContextBinding, WSHttpContextBinding which could help context re-creation on cross machine environment.But I have no production implementation knowledge to provide example.
This article should help you to know more...
There are three seperate but connected issues here:
Your design requires that you maintain state between calls
You are dependent upon getting to the same server each time (since you store state in memory)
You have a limit of 200 connections per server
A solution where you are dependent on coming back to the same server will not work (well) on Windows Azure.
You could implement a Sticky IP cluster, that would solve most of your problems, but it would not guarrantee that no more than 200 connections are on one server. For the most part this would be OK.
You could store the cache in Appfabric Cache, then it would not matter which server you returned to.
You could redesign your system so that all state is stored in the database.
I'd like to create a web service that an application server can contact to add itself to a list of servers implementing the application. Clients could then contact the service to get a list of servers. Something similar to how minecraft's heartbeats work for adding your server to the main server list.
I could implement it myself pretty easily, but I'm hoping someone has already created something like this.
Advanced features would be useful. Things like:
Allowing a client to perform queries on application-specific properties like the number of users currently connected to the server
Distributing the server list across more than one machine
Timing out a server's entry in the list if it hasn't sent a heartbeat within some amount of time
Does anyone know of a service like this? I know there are open protocols and servers for doing local-LAN service discovery, but this would be a WAN service.
The protocols I could find that had any relevance to your intended application are these:
XRDS (eXtensible Resource Descriptor Sequence).
XMPP Service Discovery protocol.
The XRDS documentation is obtuse, but you may be able to push service descriptions in XML format. The service type specification might be generic, but I get a headache from trying to decipher committee-speak.
The XMPP Service Discovery protocol (part of the protocol Formerly Known As Jabber) also looked promising, but it seems that even though you could push your service description, they expect it to be one of the services mentioned on this list. Extending it would make it nonstandard.
Finally, I found something called seap (SErvice Announcement Protocol). It's old, it's rickety, the source may be propriety, it's written in C and Perl, it's a kludge, but it seems to do what you want, kind-of.
It seems like pushing a service announcement pulse is such an application-specific and trivial problem, that almost nobody has considered solving the general case.
My advice? Read the protocols and sources mentioned above for inspiration (I'd start with seap), and then write, implement, and publish a generic (probably xml-based) protocol yourself. All the existing ones seem to be either application-specific, incomprehensible, or a kludge.
Basically, you can write it yourself though I am not aware if anyone has one for public (I wrote one over 10 yrs ago, but for a company).
database (TableCols: auto-counter, svr_name, svr_ip, check_in_time, any-other-data)
code to receive heartbeat (http://<you-app.com>?svr_name=XYZ&svr_ip=P.Q.R.S)
code to list out servers within certain check_in_time
code to do some housecleaning once a while (eg: purge old records)
To send a heartbeat out, you only need to send a http:// call, on Linux use wget* with crontab, on windows use wget.exe with task scheduler.
It is application specific, so even if you wrote one yourself, others can't use it without modifying the source code.