Hi,
if you want to do that in a blocking fashion (like in your sample), I'd
recommend to create an Attribute associated with the Connection.
private final Attribute<FutureImpl<HttpContent>> httpResponseAttr =
Grizzly.DEFAULT_ATTRIBUTE_BUILDER.
createAttribute("HttpResponseAttribute");
......
// Called in parallel from many threads
public MyResponse makeRequestToServer(MyRequest m) {
GrizzlyFuture<Connection> connectionGrizzlyFuture =
this.transport.connect(this.serverName, this.serverPort);
Connection connection = connectionGrizzlyFuture.get();
FutureImpl<HttpContent> responseFuture =
Futures.<HttpContent>createSafeFuture();
httpResponseAttr.set(connection, responseFuture);
connection.write(m);
final HttpContent response = responseFuture.get();
}
class MyClientFilter extends BaseFilter {
public NextAction handleRead(FilterChainContext ctx) throws IOException {
// process the response message from the server
FutureImpl<HttpContent> responseFuture =
httpResponseAttr.get(ctx.getConnection);
responseFuture.result(httpContent);
return ctx.getStopAction();
}
}
If you want HTTP client to work in non-blocking fashion - you probably
need to introduce a callback interface, which will be notified once a
response is received.
WBR,
Alexey.
On 22.05.14 05:38, Johan Maasing wrote:
> Thanks, that wasn't so hard :-)
>
> I am still confused about the second part. What design has people used
> to solve multi-threaded clients? Assuming something like the below:
>
> // Singleton instance
> class Client {
> private TCPNIOTransport transport
> // Only called once
> public void startup() {
> FilterChainBuilder cb = FilterChainBuilder.stateless();
> cb.add(new MyClientFilter()) ;
> transport =
> TCPNIOTransportBuilder.newInstance().build();
> transport.setProcessor(cb.build());
> transport.start();
> }
>
> // Called in parallel from many threads
> public MyResponse makeRequestToServer(MyRequest m) {
> GrizzlyFuture<Connection> connectionGrizzlyFuture =
> this.transport.connect(this.serverName, this.serverPort);
> Connection connection = connectionGrizzlyFuture.get();
> connection.write(m);
> //How to get the response the filter created??
> }
> }
>
> class MyClientFilter extends BaseFilter {
> public NextAction handleRead(FilterChainContext ctx) throws IOException {
> // process the response message from the server
> MyResponse result = ... // How to get this back to caller thread?
> return ctx.getStopAction();
> }
> }
>
> Cheers,
> JM
>
>
> 2014-05-21 22:41 GMT+02:00 Oleksiy Stashok <oleksiy.stashok_at_oracle.com
> <mailto:oleksiy.stashok_at_oracle.com>>:
>
> Oh, jusr realized it's HTTP server example, but still it might be
> useful sample for you, on client side the code will look
> similarly, except that you don't need to send response :)
>
> WBR,
> Alexey.
>
>
> On 21.05.14 13:35, Oleksiy Stashok wrote:
>> Hey Johan,
>>
>> On 21.05.14 05:28, Johan Maasing wrote:
>>> I'm going through the tutorials (for 2.3.12) making a simple
>>> HTTP client. I followed this
>>> https://grizzly.java.net/httpframework.html#/Samples which works
>>> fine.
>>>
>>> However I get a bit stuck on how to modify the sample to make
>>> the filter stateless.
>>> My use case is that I will have many threads making the same
>>> type of HTTP-requests to the same end-point. So I guess that I
>>> should set up the filter chain and start the transport once as a
>>> singleton. Then I use transport.connect and transport.write in
>>> each "client" thread.
>>> Will there ever be the case that my filter will be called
>>> several time for the same response - I'm thinking about
>>> how/where to accumulate in memory the entire response body if
>>> that is the case?
>> I think here is the Filter sample, which may help you:
>>
>> /new BaseFilter() {//
>> // @Override//
>> // public NextAction handleRead(FilterChainContext
>> ctx) throws IOException {//
>> // final HttpContent requestContent =
>> ctx.getMessage();//
>> // if (!requestContent.isLast()) { // if it's not
>> the last content chunk - keep accumulating the response content//
>> // return ctx.getStopAction(requestContent);//
>> // }//
>> ////
>> // HttpRequestPacket request = (HttpRequestPacket)
>> requestContent.getHttpHeader();//
>> // HttpResponsePacket response =
>> request.getResponse();//
>> //
>> // final Buffer payload =
>> requestContent.getContent();// // retrieve the entire response
>> payload
>> ////
>> // HttpContent responseContent =
>> response.httpContentBuilder().//
>> //content(payload).last(requestContent.isLast()).build(); //
>> build the response//
>> //ctx.write(responseContent); // send the response back on the
>> same connection//
>> // return ctx.getStopAction();//
>> // }/
>>
>>
>> Please let me know if you have more questions.
>>
>> WBR,
>> Alexey.
>>
>>
>>>
>>> How do I return the response to the calling thread? In the
>>> sample the filter gets a future from the caller in the
>>> constructor to return the result to the caller. But this won't
>>> work if I set up the chain once and it is shared between threads.
>>>
>>> Any pointers are appreciated.
>>>
>>> Cheers,
>>> JM
>>
>
>