-1

My purpose is to use WebSockets with own TCP/IP or ISO/OSI stack. I want to load balance all requests from the client to the application servers (as we know WebSockets can work only with one server which has established a connection). I want to be able to connect to one node and send requests to any node.

The algorithm is the next:
1. Client establishes a connection with one of the node behind the load balancer.
2. Client sends data through the WebSocket to the load balancer.
3. Load balancer receives the data and sends it to any server.
4. Server sees the data and sends it to the application. Even if the connection hasn't been established the server doesn't drop packets it just sends the packets to the application.

In this situation we can load balance WebSockets requests easily. I tried to understand how to to rewrite TCP/IP stack and let packets go directly to the application in user space but I am confused.

Do we need to use DPDK for it? Is yes then can you show a minimum example how to receive and send packets directly or how to skip connection checking? If no then what do we need to use in this situation?

Oleksandr
  • 3,574
  • 8
  • 41
  • 78
  • 1
    Rewrite TCP/IP stack? Good luck with that. If you describe the actual problem (without describing your sense of a solution), then we might be able to help you with a much more practical solution. We also need to know what type of client this is (browser, custom code, etc...) and what its capabilities are. – jfriend00 Oct 25 '16 at 12:39
  • FYI, you can't send packets to an application that isn't either already connected to your server or is itself a server that you can connect to. There has to be some sense of a connection in order to send over TCP. There are other protocols such as UDP (and others) with different properties/characteristics, but you've given us no real sense of the actual problem or the constraints of your two endpoints for us to know what else could be suggested. – jfriend00 Oct 25 '16 at 12:43
  • I have to process packets in the user space. By default transport layer is handled by Linux OS but DPDK can process it in the user space. I want to change a little bit the TCP protocol. Let's call it Changed_TCP. Clients is browsers. But I don't know where to start. – Oleksandr Oct 25 '16 at 12:45
  • The real problem is that you can't load balance WebSockets like HTTP requests. So, to change it I want to change a TCP protocol or add my own implementation of the protocol. – Oleksandr Oct 25 '16 at 12:48
  • Step 4 is not possible with a browser. You have to have an established webSocket connection (or an http connection that you can use server sent events) in order to be able to send directly to a browser. – jfriend00 Oct 25 '16 at 12:49
  • 1
    You can load balance incoming webSocket connections just fine. You can't move a webSocket connection to a new server once it is established, but if you have the right cooperating client, you can send it a message to reconnect so you can reload balance it. Still don't know what problem you're actually trying to solve. – jfriend00 Oct 25 '16 at 12:50
  • Yes step 4 is not possible with a browser. But if our "Changed_TCP" protocol can imitate "established webSocket connection" then it is possible. Browser will think that connection is established but in reality it won't. Then when client will send requests to the server (which has imitated an established a connection) the load balancer in fact will send a request to totally different server. And that server will accept the request even if it hasn't established a connection (as UDP does). – Oleksandr Oct 25 '16 at 12:56
  • In other words I have to be able to skip connections checks when we use TCP. By default Kernel does it for us. – Oleksandr Oct 25 '16 at 13:00
  • TCP is a stateful protocol (and this state is used to help prevent hijaack attacks). You cannot maintain a virtual connection without maintaining that state somewhere. You could proxy the connection so the actual connection with client is to a proxy and the proxy then establishes a tunnel to whatever server you want. But, in general, it is much simpler to just ask the client to reconnect if you need to reload balance or force it to reconnect by just dropping the connection on the server. – jfriend00 Oct 25 '16 at 13:00
  • Maybe I have overreacted. I have read a facebook whitepaper where they explained that Linux Kernel TCP stack implementation isn't suitable for high load servers. So, they rewrote TCP/IP stack in user space (directly from interface). And now they handle all packages in application level. I don't know if they use their own protocols or just improved algorithms. – Oleksandr Oct 25 '16 at 13:08
  • Until you have to scale to the size that Facebook does and have a really smart team of people you can put on that project, you should be looking for massively simpler ways to solve your problem (and I don't even think what Facebook did would solve your problem anyway). – jfriend00 Oct 25 '16 at 13:11
  • 1
    If your problem is just that you want to be able to re-load balance a webSocket connection, then just write a few lines of code in the client that when it receives a "reconnect" message, it will drop the current connection and re-establish a new connection, thus letting your server farm reload balance it anytime it wants. Then, set up proper load balancing on all incoming webSocket connections (which FYI, all start as an HTTP request with an "upgrade" header on them). – jfriend00 Oct 25 '16 at 13:12
  • Thank you for help. Yes, I think it is great idea. I don't know why but I haven't thought about reconnection before you said it. Thanks again – Oleksandr Oct 25 '16 at 13:19

1 Answers1

1

If you just want to be able to reload balance an existing webSocket connection, then with a few lines of client code, you can send the client a "reconnect" message and the client will drop the current webSocket connection and then reconnect a new connection.

This reconnect will allow your server farm to reload-balance that new connection.

Remember that an incoming webSocket connection starts life as an HTTP request with an "upgrade" header on it so that's what you will be looking for with your load balancing.

If you use socket.io at both client and server (a messaging layer on top of webSocket), then it will automatically reconnect so you could even just drop the connection at the server and then socket.io will automatically reconnect without any new client code.

jfriend00
  • 683,504
  • 96
  • 985
  • 979