On 2012-06-05 10:09, Robert Mitschke wrote:
Dear Sorin,
thank you very much for your thoughts and shared experience on this. Doing
it as a protocol handler I guess does work. In the protocol handler I could
then still call the hook for processing a http request that I am creating
based on my proprietary protocol right?
When you say "process a http request" that you create you mean process
its response, don't you? Yes, you can get the response. For my SMPP
module I did with mod_proxy but I suppose you can do it with any http
client lib.
I have also thought about the shared memory approach to communicate between
the individual children. How would I go about listening on input from
shared memory without doing a polling approach?
You could open a pipe in post_config (i.e. before the parent forks its
worker children). The pipe descriptors are then inherited by all
children. In process_connection you perform a timed select on two
descriptors: the socket from the non-http client and the reading end of
the pipe. When you get a triggering third-party http request, in your
http handler you write something to the shared memory to the writing end
of the pipe. This wakes up one of the non-http handlers which can check
if the triggering request was for the client it handles and then it can
proceed with pushing on the non-http socket.
I guess in my usual process connection I would create some kind of a table
of the open connections. Then I would spawn a separate thread in my
initialization that listens to input on the shared memory. I need to
respond to such input even if there is no incoming data on the connection
and the normal connection processing is not taking place. If that input is
there my self created thread determines on which connection to push out the
data and pushes it out by simply calling the corresponding output filter
chain, correct?
No, I don't think the thread is necessary. As I said above, each
non-http-processing thread performs a select that contains the pipe
reading end in its descriptor set.
When the select wakes up on socket activity => it handles the
non-http-data coming from the client.
When the select wakes up on pipe activity => it checks the shared memory
if it should write something to its client.
When it wakes up on a timeout => it writes something to its client.
Is there an apr construct that I can use to block this thread on instead of
frequent polling? I guess reusing the mpm somehow to give me a multitude of
threads that will serve my shared memory input (or I could use something
like a pipe right?) is out of the question right? Could I wrap a connection
filter around my internal (shared memory or pipe) connection and have the
mpm serve my requests in this way?
Does anyone know of an existing module that solves a similar problem that I
could look at?
Again thank you for your input,
Robert
2012/6/5 Sorin Manolache<sor...@gmail.com>
On 2012-06-04 18:40, Robert Mitschke wrote:
Hi everybody,
I am attempting to write a module that implements a binary protocol that
is
not http and is not fully request and response based using apache. I have
looked at mode echo and some others and I have Nick Kew's book.
I want my module to convert incoming messages into http requests so that
Apache is going to serve them using normal application server
infrastructure. This is what I, based on the info I have can easily do
using an input and output filter.
What I also need the protocol to be able to do is to send messages to the
client with no incoming data from the client. This may be based on a
timeout or based on a request coming from somewhere else (a tier-2
application server sending me a request on a totally different
connection).
From what I have read so far, I could not find a hook that allows me to
do
so. The only way that I could figure out how to do that is to modify
http_core.c and in ap_process_http_sync_**connection query for either the
timeout or the separate even to have occured using some shared memory
technique. This however does not feel right to me. I would ideally like to
keep using http_core as it is without touching it.
Is there a way for me to wake up trigger the input filter chain even when
there is no data on the actual connection? I could then create a request
from the context of my persistent connection for a handler that I have
written that triggers the output filter chain to send the correct message.
Or even better is there a way I can trigger the output filter chain? Are
there hooks for this purpose?
I would very much appreciate a hint in the right direction.
Hello,
As your protocol is not http, I think that you should not execute
ap_process_http_*_connection. ap_process_http_*_connection is a callback
placed on the process_connection hook. I would suggest that you place your
own protocol-specific callback on the process_connection hook. In your
callback you get the socket descriptor and you perform "select" syscalls
with timeout on the descriptor in a loop to get the timeout behaviour.
If you want to push data upon an incoming http request from a third-party,
I think you cannot avoid the shared memory approach. The process that
handles your http request has somehow to communicate with the process in
which you handle the non-http connection to your client.
I've written something similar for SMPP and I remember I considered the
filter implementation alternative but ultimately I did it without filters.
Sorin
Best regards,
Robert