Can someone help me please?
I'm writing client-server application. Server and client are connected with websockets.
Pipeline for Server:
ChannelPipeline pipeline = pipeline();
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("aggregator", new HttpChunkAggregator(65536));
pipeline.addLast("encoder", new HttpResponseEncoder());
pipeline.addLast("handler", new WebSocketServerHandler());
Pipeline for Client:
final WebSocketClientHandshaker handshaker =
new WebSocketClientHandshakerFactory().newHandshaker(
uri, WebSocketVersion.V13, null, false, customHeaders);
pipeline.addLast("decoder", new HttpResponseDecoder());
pipeline.addLast("encoder", new HttpRequestEncoder());
pipeline.addLast("ws-handler", new WebSocketClientHandler(handshaker));
This application works like a proxy - server get httprequest from outside, then sends it to client via websockets. Client receives it and sends it to modificated specified url, receives response and sends it back to server via websockets. Server receives this response and writes data into Channel that requested it.
The main question for now - what is the best way of converting HttpRequest into WebSocketFrame and back? Current idea is to read HttpRequest in string and then send it as TextWebSocketFrame. In this situation I think I'll need to replace those standart decoder that are specified for server and client currently for do not make double conversation. I did not find such decoder in Netty.
But mayby this is the bad way and there exists some more good decision?
Many thanks for answers! I'm new in netty.
Best regards
If you are planning to encapsulate the entire HTTP Request, then I think you are on the right track in sending it via a BinaryWebSocketFrame.
Related
I am hoping someone can point me in the right direction. I have a CF2021 Server which uses a Node.js websocket server and CF pages (via javascript) as a client. Messages from user to user work as expected, so no issue there.
This CF Server also has a custom API built using CFML that handles and routes inbound SMS messages. My question is; what would be the best way to send the SMS message (by now its json) to the Node.js websocket to it can send it to the user(s).
I tried using the same javascript that the browser client uses, but it appears that the CFML API script is "browser-less", so that doesn't work, or should it?
I thought something like Apache Groovy may be the solution, but I am having difficulties with any websocket example I have found.
Any suggestions would be greatly appreciated.
thanks in advance
Flow matters.
If you want to handle an incoming message by delivering it to all currently logged in users who are subscribed to messages of the current sort: set up your message handler to deliver using lucee/adobe-coldfusion websockets. Be forewarned, Lucee takes some setup time, but once running, it is a great solution.
If you don't need immediate delivery, or you need a super simple solution: I actually have had some success with "Long Polling" you just have to remember to use "flush" early in the request, before any pause/sleep, then loop your message lookup requests for new data, with a 1-5 second delay between each loop. Once new data is found, I like to return the request to the client, close that polling request and start a new polling request using the client side. I typically won't poll for more than 60 seconds. Even if the returned json object is empty.
Small question on how to send multiple requests using a Java Spring WebClient to a HTTP2 enabled server, leveraging HTTP2 as client please.
I have a Java List/Iterator of payloads I need to send one after another to a third party server. I am the client.
The third party server, which I have no control over, was first HTTP1 only.
Recently, they migrated to HTTP2, and they now fully support HTTP2.
When it was still HTTP1 enabled, I was using this code: (note the http1Client vs http2Client), here is what I am trying
private static Iterator<String> sendRequestsLeverageHttpTwo(Iterator<String> requestsPayload) {
List<String> linkedList = new LinkedList<>();
while (requestsPayload.hasNext()) {
String requestPayload = requestsPayload.next();
HttpClient http1Client = HttpClient.create().wiretap(true).protocol(HttpProtocol.HTTP11); // was using this when the server only supports HTTP1
HttpClient http2Client = HttpClient.create().wiretap(true).protocol(HttpProtocol.H2); //now using this as the server supports HTTP2
final WebClient webClient =
WebClient.create().mutate().defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE, HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.clientConnector(new ReactorClientHttpConnector(http2Client)).build(); //replace http1Client -> http2Client
final String response = webClient.post().uri("http://the-http-two-enabled-server/api").body(BodyInserters.fromValue(requestPayload)).retrieve().bodyToMono(String.class).block();
if (!"".equals(response)) {
linkedList.add("OK");
}
}
return linkedList.iterator();
}
The third party server is now supporting HTTP2, I swapped for the http2Client.
Things "work", the third party server told me they are able to see in their access logs, all my requests are now HTTP2, happy.
The problem is, I realize on the client side, me, I am using HTTP2 here like HTTP1!
Meaning, candid as I am, I just swapped the HttpClient, and don't think I am leveraging any of HTTP2 technology.
Looking at this code, I am really just doing the same as before, but just with HttpProtocol.H2. I do not think this is fully leveraging the step up from HTTP1 to HTTP2, please correct me if I am wrong.
My question is, how to properly fully leverage the step up HTTP2 while sending this collection of payloads to the HTTP2 enabled back end please?
Thank you
I have a http route /checkout which initiates a workflow process in Zeebe. The checkout route will return 200 response straight-away to calling client. Now, workflow will run for a while. So to push the response back to client after completion, I have a /sse separate route for server-sent events. Here, I will store all the client connection in a global map.
My doubt is how do I find the exact client to send the response back through sse once?
Example: Client A listening to /sse and calls /checkout endpoint which will return 200. The /sse has to return the response to client A after completion.
Currently, I thought of using cookie to identify the client. Is there a better way?
If you are already using cookies in your app than that's the way to go since the very purpose of cookies is identifying the client, so if you already have that, you should use it.
But if you rely on another authentication mechanism (like JWT), what you could do is using the url as a query.
So in the client instead of
let eventSource = new EventSource("/sse");
Do
let eventSource = new EventSource("/sse?authorization=jwt_token");
In the backend, you would validate that token, extract the Client ID and hit that global map with it to retrieve the corresponding connection.
(PS: instead of a global map, you should use a proper store, like redis, or an embedded key/value store like bbolt)
can anyone help on below issue?
I have two microservices A and B where service A sends request to B, B fetches data from database and sends the response back to A, based on received data, I am doing few operations.
At present, I am using Http client call.I don't want to use http request? How can I proceed further?
Thanks,
Revathi
If you want to use HTTP to communicate between 2 services, you need a HTTP client that allows you to specify the parameters related to your request. Example in Java (more details here):
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("<YOUR_ENDPOINT>"))
.build();
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
If you don't want to use HTTP 1.1, you can take a look at gRPC, there are plenty examples on the web on how to use both of them
I'm picking my way through the dartiverse_search example from the welcome page in dart editor. I see that it uses a path route to decide whether to transform a request into a websocket:
// The client will connect using a WebSocket. Upgrade requests to '/ws' and
// forward them to 'handleWebSocket'.
router.serve('/ws')
.transform(new WebSocketTransformer())
.listen(handleWebSocket);
Is it possible to turn a request into a websocket without using a routing path, for example using a query string to the root url?
You can specify any condition for upgrading to a WebSocket connection. You can even upgrade any connection request to a WebSocket connection without specifying a condition like this:
WebSocketTransformer.upgrade(request).then((WebSocket websocket) {
websocket.listen((String text) {
// process sent data
});
websocket.add(JSON.encode("Hello"));
});
If the request is not a valid web socket upgrade request a HTTP response with status code 500 will be returned. Otherwise the returned future will complete with the [WebSocket] when the upgrade process is complete.