How to use netty to run a websocket server and not process other types HTTP requests (like GET and POST). - websocket

I'm using Netty 4.1.1 to run a websocket server. Only want to process websocket and not process other types HTTP requests (like GET and POST).
In Netty API for WebSocketServerProtocolHandler, it says:
"This handler does all the heavy lifting for you to run a websocket server. It takes care of websocket handshaking as well as processing of control frames (Close, Ping, Pong). Text and Binary data frames are passed to the next handler in the pipeline (implemented by you) for processing. See io.netty.example.http.websocketx.html5.WebSocketServer for usage. The implementation of this handler assumes that you just want to run a websocket server and not process other types HTTP requests (like GET and POST)."
But I can't find io.netty.example.http.websocketx.html5.WebSocketServer.
Any idea? Thanks.

It seems that the doc is outdated.
You can refer io.netty.example.http.websocketx.server.WebSocketServer.
If you want to check io.netty.example.http.websocketx.html5.WebSocketServer, you can checkout commit 2704efc.

Related

Read_reply in tarantool-c is too slow

I am setting up a c server and used tarantool as databased using tarantool-c. However, everytime I setup read_reply() the request per second tanks so much its like using mysql. How to fix it?
We had the discussion with James and he shares the code. The code implements the http server and this is how it processes a request:
Accept a new incoming http request.
Send a request to tarantool (using binary protocol).
Wait for a reply from tarantool (synchronously, unable to handle other incoming http requests).
Answer to the http request.
The root of the problem here is that we unable to utilize full network bandwith between the http server and tarantool. Such server should use select() / poll() / epoll() (on Linux) / kqueue (on FreeBSD) or a library like libev to determine whether it is able to write to a socket, read from it or accept a request.
Let me describe in brief how it should operate to at least utilize a network as much as possible (when doing it from one thread) in the set of rules of when-X-then-Y kind:
When a new http request arrive it should register the need to send a request to tarantool (let me name it pending request).
When a socket to tarantool is ready for write and there is at least one pending request the server should form a request to tarantool, save its ID (see tnt_stream.reqid) and write the request to the socket.
When the socket to tarantool is ready to read the server should read a reply from tarantool, match its ID (see tnt_reply.sync) against saved one and write a response to an http client, then close the socket to the client.
If http keepalive / pipelining need to be supported, the server needs to check a socket to an http client for readiness to perform read() / write(). Also it need to register pending http responses rather then write it just when they appears.
Aside of that HTTP itself is not easy to implement in a proper way: it always give you surprises if you don't control implementations of both client and server.
So I will describe alternatives to implementing its own http server, that are compatible with tarantool and able to operate with it in asynchronous way to achieve good performance. They are:
Using http.server tarantool module that allows to process http requests right in tarantool w/o external service and w/o using a connector to tarantool.
Using nginx_upstream_tarantool nginx module that allows to perform a request to tarantool from nginx using the binary protocol.
There are cons and pros for both of these ways. However http.server disadvantages can be overcomed with using nginx as frontend to proxying requests to tarantool(s) saving http.server advantages.
http.server cons:
No https support.
Single CPU bound / single tarantool instance bound.
Possibly worse performance then nginx (but not much).
Possibly worse support of HTTP caveats (but I don't know one).
http.server pros:
Simpler to start developing.
Simpler in configuration / deployment: parts of an application configuration do not spread across configs for tarantool and nginx.
nginx_upstream_tarantool cons and pros are reverse of http.server ones. Also I would mention specifically that nginx allows you to balance load across several tarantool instances, which may form a replication group or may be sharding frontends. This ability can be used to scale a service in the sense of desired performance as with proxying to http.server as well as with nginx_upstream_tarantool.
I guess you also interested in benchmarking results for http.server and nginx_upstream_tarantool. Look at this measurement. Note however that it is quite synthetic: it performs small requests and answer with small responses. Real RPS numbers may be different depending of size of requests and responses, hardware, whether https is needed, etc.

Why does SIgnalR prefer Forever Frames over polling?

I am learning to use SignalR and so far I had success in doing so. I can implement Hubs, I can implement business logic, I can invoke client-side functions from server for whom I want, I can invoke server-side methods from client-side, this stuff is great. The thing puzzling me is the theory.
In fact, I gathered info from this video. SignalR is using WebSockets, which provide a full duplex channel over a single TCP connection. If no WebSockets are available, then the fallback protocol will be EventSource. If that is unavailable, then a Forever Frame will be used. If that is unavailable, then Long Polling will be used. It is rather strange for me that a very hacky solution, like a forever frame is preferred over the older convention and I am interested about the rationale behind SignalR's decision to have forever frames as the third option and polling as fourth option.
I have tried to find out the answer to this question and I found out that it is rumored that there is a 3x max latency time in the case of long polling compared to forever frames. Is this a fact and if so, is it a fact for all browsers, or for a subset?
foreverFrame works a bit like serverSentEvents - there is one long running http request which the server never terminates but uses to push data to the client. longPolling works differently - there is a poll http request which is being closed by the server each time there is data for the client to read (or a timeout expires). If the client wants to read more data it needs to open a new http request which again will be closed by the server as soon as there is any data for the client. In other words, in case of foreverFrame the server is pushing data to the client using an already established channel while in case of longPolling the client is continuously creating http requests to get the data from the server.

The theory of websockets with API

I have an API running on a server, which handle users connection and a messaging system.
Beside that, I launched a websocket on that same server, waiting for connections and stuff.
And let's say we can get access to this by an Android app.
I'm having troubles to figure out what I should do now, here are my thoughts:
1 - When a user connect to the app, the API connect to the websocket. We allow the Android app only to listen on this socket to get new messages. When the user want to answer, the Android app send a message to the API. The API writes itself the received message to the socket, which will be read back by the Android app used by another user.
This way, the API can store the message in database before writing it in the socket.
2- The API does not connect to the websocket in any way. The Android app listen and write to the websocket when needed, and should, when writing to the websocket, also send a request to the API so it can store the message in DB.
May be none of the above is correct, please let me know
EDIT
I already understood why I should use a websocket, seems like it's the best way to have this "real time" system (when getting a new message for example) instead of forcing the client to make an HTTP request every x seconds to check if there are new messages.
What I still don't understand, is how it is suppose to communicate with my database. Sorry if my example is not clear, but I'll try to keep going with it :
My messaging system need to store all messages in my API database, to have some kind of historic of the conversation.
But it seems like a websocket must be running separately from the API, I mean it's another program right? Because it's not for HTTP requests
So should the API also listen to this websocket to catch new messages and store them?
You really have not described what the requirements are for your application so it's hard for us to directly advise what your app should do. You really shouldn't start out your analysis by saying that you have a webSocket and you're trying to figure out what to do with it. Instead, lay out the requirements of your app and figure out what technology will best meet those requirements.
Since your requirements are not clear, I'll talk about what a webSocket is best used for and what more traditional http requests are best used for.
Here are some characteristics of a webSocket:
It's designed to be continuously connected over some longer duration of time (much longer than the duration of one exchange between client and server).
The connection is typically made from a client to a server.
Once the connection is established, then data can be sent in either direction from client to server or from server to client at any time. This is a huge difference from a typical http request where data can only be requested by the client - with an http request the server can not initiate the sending of data to the client.
A webSocket is not a request/response architecture by default. In fact to make it work like request/response requires building a layer on top of the webSocket protocol so you can tell which response goes with which request. http is natively request/response.
Because a webSocket is designed to be continuously connected (or at least connected for some duration of time), it works very well (and with lower overhead) for situations where there is frequent communication between the two endpoints. The connection is already established and data can just be sent without any connection establishment overhead. In addition, the overhead per message is typically smaller with a webSocket than with http.
So, here are a couple typical reasons why you might choose one over the other.
If you need to be able to send data from server to client without having the client regular poll for new data, then a webSocket is very well designed for that and http cannot do that.
If you are frequently sending lots of small bits of data (for example, a temperature probe sending the current temperature every 10 seconds), then a webSocket will incur less network and server overhead than initiating a new http request for every new piece of data.
If you don't have either of the above situations, then you may not have any real need for a webSocket and an http request/response model may just be simpler.
If you really need request/response where a specific response is tied to a specific request, then that is built into http and is not a built-in feature of webSockets.
You may also find these other posts useful:
What are the pitfalls of using Websockets in place of RESTful HTTP?
What's the difference between WebSocket and plain socket communication?
Push notification | is websocket mandatory?
How does WebSockets server architecture work?
Response to Your Edit
But it seems like a websocket must be running separately from the API,
I mean it's another program right? Because it's not for HTTP requests
The same process that supports your API can also be serving the webSocket connections. Thus, when you get incoming data on the webSocket, you can just write it directly to the database the same way the API would access the database. So, NO the webSocket server does not have to be a separate program or process.
So should the API also listen to this websocket to catch new messages
and store them?
No, I don't think so. Only one process can be listening to a set of incoming webSocket connections.

Does the built-in http server implement non-blocking I/O?

This is a first server-side swift framework available now. I am interested to use it for high traffic mobile app server.
Does this swift based framework implement the non-blocking I/O http server?
Yes, the internal networking in Perfect is all non-blocking. This is the case if you are doing raw TCP comms., using the built-in HTTP server or the FastCGI server. Check out the NetTCP and NetNamedPipe classes. They take callbacks when you connect, accept, read or write data. All of the relevant functions take a timeout parameter as well. You can optionally accept custom server connections in a blocking loop.
The individual web handlers are non-blocking as well in that you call a callback to tell the system that you are done with the request. The system will complete the current request and await others utilizing keep-alive.

Continue pipeline after WebSocketServerProtocolHandler when no upgrade specified?

I have WebSocketServerProtocolHandler handler on the root path, where I also accept regular HTTP requests. However, WebSocketServerProtocolHandler wont let me use my HTTP request, as it assumes everything is web sockets and responds with:
not a WebSocket handshake request: missing upgrade
Can I simply continue execution of the pipeline after WebSocketServerProtocolHandler when upgrade to web sockets is not required? In other words, I need both HTTP and WebSockets operate on same address.
Yeah, I could probably copy/paste and do my own WebSocketServerProtocolHandler, but is there better way?
The javadoc for WebSocketServerProtocolHander refers you to the io.netty.example.http.websocketx.html5.WebSocketServer example. However it might not be entirely obvious what's happening here.
If you take a look at the source code for WebSocketServerInitializer you can see that by default it sets up a fairly standard HTTP pipeline. This is because, as you know, the upgrade request is a HTTP request. The magic happens in the handleHttpRequest method of WebSocketServerHandler. It falls through to line 96 and assumes it's an upgrade request (you might want to actually check). It creates a WebSocketServerHandshaker and starts the handshake. The trick is that it automatically reconfigures the pipeline to handle web socket traffic so you don't have to. Take a look at the handshake method in WebSocketServerHandshaker to see what's going on.

Resources