Bidirectionnal protocol working when changing networking - networking

I would like a bidirectional protocol working between two computer to send data between each other that will continuous to work when i change network (in java).
I tried to use websocket to send data between the two computer (not that the two computer are client and server the server is in amazon with a static ip address,while the client is in my local network) i this is the behaviour observed.
When i try to connect the client to the server the communication works and data are sent very well between each other.
But when i switch the client from one network to another network.
but when i switch my client from one network to another network (because the network lost internet connection),obviously the client has changed ip address, the communication between the computers (client are server) doesn't work any more. How can i do such that this communication still available?
If it isn't possible, is there any bidirectionnal protocol that still working when i switch the client from one network to another one?

I cannot think to another bidirectional protocol that automatically handles ip switch. I just can guarantee there is no "standard" protocol that does it.
It is something that you can handle at application level on top on WebSocket.
For example:
server side: you assign an univocal id to every client. You keep track of connected clients and stop tracking them when they are disconnected for too long time. If a client with a known id asks to start a websocket connection you can continue from where you left off, else you assign a new id;
client side: when the connection goes down (I suppose onerror event) you periodically try to start a new websocket handshake sending your id;
of course using a simple id is not so secure and it does not take into account if you reload the page or open it from another tab. Anyway those problem can be easily solved in lot of different ways (for example if the user are authenticated).

Related

SignalR OnConnected firing on different server to the one which it's actually connected

I'm using SignalR and a web farm in IIS, currently with 3 servers and requests are load balanced via ARR.
There are certain external events that happen which I want to be processed by the server to which the client is connected. So I want to track which of the 3 servers the client is currently connected.
I thought that I could do this using OnConnected and within that method store the MachineName against the ConnectionID in redis.
The problem is that OnConnected seems to get called an a different server to the one that the client is connected to.
Upon investigating, it seems that there are three calls, one to /negiotate one to /connect and one to /start. The /connect seems to be the websocket connection that is kept up for the duration, the others are just transient.
These three connections can happen on different servers, and it seems that the websocket connection can be to server A (so that's the server that the client's SignalR connection is going to), but the OnConnected gets fired on server B.
I was wondering if I'm overlooking something that will let me see which server the SignalR connection is actually connected to?
Thanks,
Will
If you are going to use a web farm, then you need to implement a backplane to track all of the messaging.
https://learn.microsoft.com/en-us/aspnet/signalr/overview/performance/scaleout-in-signalr
Without a proper backplane implementation its impossible to do what you want to do.
I believe that is something you would have to save. Assuming you are using a database for mapping users, you could have an additional field such as "LoggedInOn" and store the server host name or other identifier.
However, other than some aspect of troubleshooting your are looking to do, proper send/receive of messages should cross the backplane to all servers. This way no matter which server they are connected to, messages are received.
If you have external events as you say, once they complete and a message is ready to be sent back to a client, the backplane should push that to all servers.
If that's not happening I would review the docs as Kelso Sharp stated.

Sending TCP data to a client behind NAT

I am working on a client/server program with one server (not behind NAT) and many clients that are using NAT. I need the server to be able to transfer files to the clients every so often, thus the server must be able to initiate TCP traffic when needed. I have already figured out how to do this with UDP by caching the clients' IPEndPoints and using them later.
Can anyone recommend some sample code or a project (with source) they have seen that can do this? There are lots of Chat or IM projects out there to learn from, but they generally use only UDP across NAT or only work on LANs without NAT being used. C++/C#/VB source with a solution would help a lot. Thanks.
Your best options:
Clients polls periodically to discover if new files are available. Simplest option. This may or may not scale depending on how many clients and how often they would need to poll.
All clients keep a persistent TCP connection to the server. Server sends files to a specific client when ready. Avoids the polling overhead of #1, but might have issues if the number of clients reaches into the thousands if you haven't designed your service to scale for the C10K problem.
Clients connect to a notification server which is designed to handle many clients simultaneously connected. Client sends its notification server parameters to file transfer service and disconnects. When file server has a new file available, server sends notification through notification service to tell client to connect back for an awaiting file. Client disconnects from file server after file transfer is done.

Is there a network communication protocol whose use won't require an app's user to grant permissions in Windows Firewall?

I want my client program to communicate with a server without making the user add an exception to Windows Firewall in elevated mode. Is there a way to do this? HTTP? For instance, uTorrent and Google Chrome can both be installed by a regular (non-admin) user, and both programs network quite extensively - how do they do this? Am I missing something about how the firewall and/or ports works?
Yes there is a way. Assuming that your client program is the one running on the users machine and that your client program is the one initiating communication with the server then your client program generally would not need to require end user to open any exceptions in the windows firewall as long as you stick to using http over port 80. Http on port 80 is generally open for outbound traffic (initiated by the client) and therefor you could build your communication (and if needed your own protocol) on top of the http protocol. This is the typical scenario for webserver and webbrowsers (clients).
If you need the server to initiate the communication it becomes more complex and a lot of different approaches could be used. Choice of communication channels and structure should depend on factors like whether you would want to communicate to one client at a time or many (broadcast/multicast), do you need encryption, what are your needs for speed (throughput and latency), what kind of system are you trying to build and so on.
Many webapplications achieve an effect of a server initiated communication by using special techniques called polling, long polls, comet, websockets and so on. these work through http on top of tcp/ip on port 80. Other systems employs subscription mechanisms to be able to get notified through a third part if something new has happened. If you need server initiated communications please let me now and i will try to give a better explanation on the options.

Client vs. Server terminology

I always get these two terms confused. How do you determine which side is the server and which side is the client? Is it determined by whether it's sending or receiving data? (Assuming the connection goes one-way)
Thank you,
In TCP, it's determined by the side that initiated the connection. The client initiates a connection, and the server listens for and accepts a connection. Once connected, data can flow both ways.
Definitions:
Server-side refers to operations that are performed by the server in a client–server relationship in computer networking. Typically, a server is a software program, such as a web server, that runs on a remote server, reachable from a user's local computer or workstation.
Client-side refers to operations that are performed by the client in a client–server relationship in a computer network. Typically, a client is a computer application, such as a web browser, that runs on a user's local computer or workstation and connects to a server as necessary.
If there are a lot more instances of one side of the connection than the other, the one with more instances is the client.
If one side stays running a lot longer than the other, the one that stays up longer is the server.

Standard way of using a single port for multiple sockets?

Hey I am writing an app in Twisted, and as it stands I have 4 servers bound two different ports all communicating with the client via JSON. Is there anyway to bind these 4 servers to the same port and have the interactions remain the same?
For instance say the client subscribes to two different feeds, transmitted via a direct socket.
Right now I just do like
server1.read_string()
server2.read_string()
and it will read the correct JSON string from the respective feeds. Is there anyway to maintain this type of functionality but contact my server on the same port?
I do not want to throw all of the server functionality into one massive server and partition the data by header prefixes.
I don't want to do something like
s = server.read_string()
header = s.split(//some delimiter)[0]
if (header == "SERVER1")
{
// Blahh
}
It sounds like you have many clients interacting with your servers via HTTP. The standard solution is to throw a reverse proxy between the client and your servers - that proxy then forwards connections to the appropriate server depending on the URL. The reverse proxy can run on any one of your existing servers or on its own server to lighten the load.
If your data is cachable, the reverse proxy can do caching on your results too.
There are many reverse proxies available and you will want to choose one based on what sort of workload you have. Do you need it to be highly configurable? Is the data public or based on logins? How long does each connection last / how many connections to you want to hold open at once?
Squid, Varnish, HAProxy are good reverse proxies and even Apache could do this for you.
I plan to use HAProxy for Gridspy, my project as I have many ongoing connections with my clients and want to place an orbited server in the same URL path as my django server. See This tutorial for more information on how to forward many connections on port 80 from one server to many. This tutorial is focused on Comet, but your problem is even simpler than that.
If you are considering an ongoing tcp/ip connection from the browser back to your servers, seriously consider Orbited. See this tutorial about graphs via orbited and morbidQ. Orbited will also punch through firewalls and proxies better than most custom solutions will, as it looks like normal HTTP traffic.
In order to have multiple servers running on the same machine all bound to the same port, they need to be bound to different IP addresses. The only way to bind to the same port on the same IP is to enable the socket's SO_REUSESOCKET option, but then multiple servers would be able to receive each other's inbound data, really messing up your communications.
Otherwise, having a single server that uses headers to identifies the particular feeds is best. Why do you not want to do that?

Resources