Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / January 2008

Tip: Looking for answers? Try searching our database.

Clarification on firewall issues with Java networking APIs

Thread view: 
Qu0ll - 11 Dec 2007 00:28 GMT
I understand that RMI doesn't play well with the internet because it can't
work properly when either the client or the server is behind a proxy unless
tunneling is used and that tunneling is slow and prevents callbacks from
being used.  So I get it that RMI is probably not the network API for me.

And I understand that servlets don't have this problem because they
communicate through the standard HTTP port but that servlets don't support
callbacks for non-HTML clients.  (Feel free to disagree if appropriate).

Which leads me back to NIO.  Does it suffer the same problems as RMI?
Namely, will it play well if the client is behind a proxy?  If so, why is it
that RMI can't and NIO can?

Signature

And loving it,

-Q
_________________________________________________
Qu0llSixFour@gmail.com
(Replace the "SixFour" with numbers to email me)

Arne Vajhøj - 11 Dec 2007 00:41 GMT
> I understand that RMI doesn't play well with the internet because it
> can't work properly when either the client or the server is behind a
> proxy unless tunneling is used and that tunneling is slow and prevents
> callbacks from being used.  So I get it that RMI is probably not the
> network API for me.

It is difficult but possible to get RMI through an opened port in
a firewall.

A proxy server that only knows HTTP seems as a total roadblock for
RMI to me.

> And I understand that servlets don't have this problem because they
> communicate through the standard HTTP port

The proxy server understands HTTP and forward those. Note that in
most cases client/server via HTTP through proxy server will only
work if it is on the client side.

>                                           but that servlets don't
> support callbacks for non-HTML clients.  (Feel free to disagree if
> appropriate).

It is not obvious to me what you mean with callbacks. But most
certainly the servlet does not care what type of client is requesting.

> Which leads me back to NIO.  Does it suffer the same problems as RMI?
> Namely, will it play well if the client is behind a proxy?

NIO is an API not a protocol.

Plain sockets (both normal and via NIO) will usually only be able
to go out through a proxy server if they emulate the HTTP protocol.

I you need something network allowable, then look for web services
(SOAP/HTTP).

Arne
Qu0ll - 11 Dec 2007 01:03 GMT
Thanks for your reply Arne - comments inline.

> It is difficult but possible to get RMI through an opened port in
> a firewall.
>
> A proxy server that only knows HTTP seems as a total roadblock for
> RMI to me.

Right, so RMI is definitely out then.

> It is not obvious to me what you mean with callbacks. But most
> certainly the servlet does not care what type of client is requesting.

By callbacks I mean something like "push" technology where the servlet is
able to send data to the client without the client having had to request it.
This is critical to my project and hence I have discounted servlets as a
possible solution for their inability to do this.  Are you saying that there
is a way to have push functionality from a servlet to an applet?

> Plain sockets (both normal and via NIO) will usually only be able
> to go out through a proxy server if they emulate the HTTP protocol.

I am not sure I entirely understand this... how do I have my NIO server and
client emulate the HTTP protocol?

> I you need something network allowable, then look for web services
> (SOAP/HTTP).

OK, this is something I hadn't considered.  Is it feasible and/or practical
to invoke web services from applets?  It has to be applets and not Web
Start.

Signature

And loving it,

-Q
_________________________________________________
Qu0llSixFour@gmail.com
(Replace the "SixFour" with numbers to email me)

Arne Vajhøj - 11 Dec 2007 01:28 GMT
>> It is not obvious to me what you mean with callbacks. But most
>> certainly the servlet does not care what type of client is requesting.
[quoted text clipped - 5 lines]
> saying that there is a way to have push functionality from a servlet to
> an applet?

HTTP does not allow push from server to client.

For push you should go for plain sockets.

And that does (usually) not go through proxy servers.

>> Plain sockets (both normal and via NIO) will usually only be able
>> to go out through a proxy server if they emulate the HTTP protocol.
>
> I am not sure I entirely understand this... how do I have my NIO server
> and client emulate the HTTP protocol?

Simply implement the HTTP protocol. It is rather simple to do. But
by doing that you will be limited by the HTTP protocol that
does not allow push.

>> I you need something network allowable, then look for web services
>> (SOAP/HTTP).
>
> OK, this is something I hadn't considered.  Is it feasible and/or
> practical to invoke web services from applets?  It has to be applets and
> not Web Start.

Yes. If you have a very new Java on the client you may not even need to
download MB's of jars. With older Java then ...

Note that this does not solve the HTTP problem either.

----

From a practical point of view - if you need push then:
  - plain sockets
  - server app (daemon) on the server side
  - firewalls on the client side has to allow outbound connections
  - firewall the server side has to get a port opened
  - no proxy servers only forwarding HTTP allowed
seems as the possible.

Arne
Qu0ll - 11 Dec 2007 01:38 GMT
> HTTP does not allow push from server to client.
>
> For push you should go for plain sockets.
>
> And that does (usually) not go through proxy servers.

Usually?  Are you saying it can be done?

> Simply implement the HTTP protocol. It is rather simple to do. But
> by doing that you will be limited by the HTTP protocol that
> does not allow push.

OK, no good then.  Although there is a thing called Comet which permits
push-style interaction with JSF and JSP I believe but I don't think it would
work with applets(?).

> Yes. If you have a very new Java on the client you may not even need to
> download MB's of jars. With older Java then ...
>
> Note that this does not solve the HTTP problem either.

So web services can't push either?  OK, I get it.

> From a practical point of view - if you need push then:
>   - plain sockets
[quoted text clipped - 3 lines]
>   - no proxy servers only forwarding HTTP allowed
> seems as the possible.

My ideal solution was RMI but that has been ruled out.  So my "next best
fit" is an NIO server daemon and NIO client in the applet with the caveats
that you have outlined above.  Now, I am assuming this fits the "plain
sockets" criterion you mentioned - right?

Arne, would you be able to comment on the prevalence of environments where
this would not work such as where there are proxy servers that only allow
HTTP forwarding?  i.e. is this a common setup in large businesses perhaps?

Signature

And loving it,

-Q
_________________________________________________
Qu0llSixFour@gmail.com
(Replace the "SixFour" with numbers to email me)

Arne Vajhøj - 11 Dec 2007 01:49 GMT
>> HTTP does not allow push from server to client.
>>
[quoted text clipped - 3 lines]
>
> Usually?  Are you saying it can be done?

I am saying that normally the proxy does not allow it.

But in theory you could write a proxy server that did.

>> Simply implement the HTTP protocol. It is rather simple to do. But
>> by doing that you will be limited by the HTTP protocol that
[quoted text clipped - 3 lines]
> push-style interaction with JSF and JSP I believe but I don't think it
> would work with applets(?).

Never heard about it, so I can not comment on what they do and don't.

>> From a practical point of view - if you need push then:
>>   - plain sockets
[quoted text clipped - 8 lines]
> caveats that you have outlined above.  Now, I am assuming this fits the
> "plain sockets" criterion you mentioned - right?

Yes. NIO can be used with plain sockets. I really can not see the
need for using NIO at the client.

> Arne, would you be able to comment on the prevalence of environments
> where this would not work such as where there are proxy servers that
> only allow HTTP forwarding?  i.e. is this a common setup in large
> businesses perhaps?

Yes. It is a typical corporation thing.

The firewall oes not allow outgoing connections directly from
employees PC's.

Instead they can have their browser connect to the proxy server
that forwards HTTP and maybe FTP and nothing else.

Arne
Qu0ll - 11 Dec 2007 05:37 GMT
>> Arne, would you be able to comment on the prevalence of environments
>> where this would not work such as where there are proxy servers that only
[quoted text clipped - 8 lines]
> Instead they can have their browser connect to the proxy server
> that forwards HTTP and maybe FTP and nothing else.

Is it possible for the Java program (probably at the client end) to detect
that this situation exists?  I mean if I default to using RMI, can it detect
that such a proxy system is in place and then revert to using another
method/protocol if it is?  I ask this because my testing with RMI and the
other network architectues revealed that RMI gave by far the fastest
response and I would like to use it wherever possible.

Signature

And loving it,

-Q
_________________________________________________
Qu0llSixFour@gmail.com
(Replace the "SixFour" with numbers to email me)

Arne Vajhøj - 12 Dec 2007 01:59 GMT
>>> Arne, would you be able to comment on the prevalence of environments
>>> where this would not work such as where there are proxy servers that
[quoted text clipped - 15 lines]
> with RMI and the other network architectues revealed that RMI gave by
> far the fastest response and I would like to use it wherever possible.

Try send an HTTP request directly to www.google.com, if it fails then
either Google is down or direct outbound HTTP are blocked

Or maybe it makes more sense to actually try and connect to your
server on the correct port just in case 80 is open but your
port is not.

Arne
Martin Gregorie - 12 Dec 2007 21:36 GMT
>>>> Arne, would you be able to comment on the prevalence of environments
>>>> where this would not work such as where there are proxy servers that
[quoted text clipped - 24 lines]
>
> Arne
Use "traceroute -Tp=80 google.com" to find out where the problem is.

Signature

martin@   | Martin Gregorie
gregorie. | Essex, UK
org       |

Arne Vajhøj - 16 Dec 2007 02:43 GMT
>>> Is it possible for the Java program (probably at the client end) to
>>> detect that this situation exists?  I mean if I default to using RMI,
[quoted text clipped - 12 lines]
>>
> Use "traceroute -Tp=80 google.com" to find out where the problem is.

I don't think where matters for the poster.

Arne
Martin Gregorie - 16 Dec 2007 19:04 GMT
>>>> Is it possible for the Java program (probably at the client end) to
>>>> detect that this situation exists?  I mean if I default to using
[quoted text clipped - 14 lines]
>
> I don't think where matters for the poster.

Well.... if traceroute shows its blocking in his host or the firewall
between his LAN and the wider 'net he may be able to fix the cause. If
the blockage is outside his firewall he will have to find a workround
which may mean changes to the application.

I'd want to know who/what is blocking that before I started changing things.

Signature

martin@   | Martin Gregorie
gregorie. | Essex, UK
org       |

Martin Gregorie - 12 Dec 2007 21:39 GMT
>>>> Arne, would you be able to comment on the prevalence of environments
>>>> where this would not work such as where there are proxy servers that
[quoted text clipped - 24 lines]
>
> Arne

Oops - make that "traceroute -Tp 80 google.com" (no = ).

Signature

martin@   | Martin Gregorie
gregorie. | Essex, UK
org       |

Roger Lindsjö - 11 Dec 2007 19:29 GMT
>> Simply implement the HTTP protocol. It is rather simple to do. But
>> by doing that you will be limited by the HTTP protocol that
[quoted text clipped - 3 lines]
> push-style interaction with JSF and JSP I believe but I don't think it
> would work with applets(?).

Resin's Comet seems to just be a long (timewise) request to a servlet.
As far as I can tell the application (Applet, JavaScript, etc) initiates
a HTTP request to the server (let's assume a servlet). The servlet
accepts the request, but instead of just returning an answer it hangs on
to the request/response and sends back data as it becomes available.
With Ajax they seem to be sending <script>...</script> as part of each
response as the browser will parse and execute those as they come
without waiting until the request is completed. See
http://www.caucho.com/resin-3.1/examples/servlet-comet/
Something similar could probably be implemented for applets as well.

//Roger Lindsjö
Arne Vajhøj - 12 Dec 2007 02:12 GMT
>>> Simply implement the HTTP protocol. It is rather simple to do. But
>>> by doing that you will be limited by the HTTP protocol that
[quoted text clipped - 14 lines]
> http://www.caucho.com/resin-3.1/examples/servlet-comet/
> Something similar could probably be implemented for applets as well.

But how will that work with many clients ?

Arne
Roger Lindsjö - 12 Dec 2007 07:31 GMT
>>>> Simply implement the HTTP protocol. It is rather simple to do. But
>>>> by doing that you will be limited by the HTTP protocol that
[quoted text clipped - 16 lines]
>
> But how will that work with many clients ?

Probably very badly. I was just commenting on what Comet was and how the
"Push" works and how to apply the same technology to applets.

//Roger Lindsjö
RedGrittyBrick - 11 Dec 2007 10:39 GMT
> HTTP does not allow push from server to client.

This might be of interest ...
http://en.wikipedia.org/wiki/Push_technology#HTTP_Server_Push
http://wp.netscape.com/assist/net_sites/pushpull.html
http://alex.dojotoolkit.org/?p=545
Nigel Wade - 11 Dec 2007 14:57 GMT
> I understand that RMI doesn't play well with the internet because it can't
> work properly when either the client or the server is behind a proxy unless
> tunneling is used and that tunneling is slow and prevents callbacks from
> being used.  So I get it that RMI is probably not the network API for me.

RMI plays perfectly well with the Internet, but not firewalls. I think RMI works
in a very similar way to portmapper. The rmiregistry listens on a well-known
port. A RMI server registers its service with the rmiregistry, and is either
assigned or tells the registry the port that it actually listen on. A RMI
client asks the rmiregistry for the "location" of a particular service, and the
rmiregistry replies telling the client what host/port the server is listening
on.

For the above to work through a firewall the client must be able to connect to
the server both on the rmiregistry port and the port on which the server is
listening. This will normally cause problems with firewalls because they are
not configured to allow this to happen for dynamic ports. It may be possible
for an RMI server to request a specific port and register that, but I'm not
certain (RMISocketFactory.createServerSocket(int port)?). That way it might be
possible to open only the rmiregistry port and the specific RMI server ports in
the firewall.

> And I understand that servlets don't have this problem because they
> communicate through the standard HTTP port but that servlets don't support
> callbacks for non-HTML clients.  (Feel free to disagree if appropriate).

Servlets can communicate via any port. The initial connection is made to the
servlet container on whatever port that happens to be listening on. It may be
80, or 8080 or any other port. The socket is passed to the servlet's service
routine and the servlet can send a reply on that already established socket.
There is no requirement for communication to be HTTP unless you extend
HttpServlet. A GenericServlet can use any protocol (layered over TCP/IP).

Servlets can also open any other socket they wish, including initiating callback
to a client. If you do this in the service method you are likely to get
deadlock if the servlet attempts to initiate a new communication channel with
the client whilst the client is waiting for the servlet to respond to its
initial request. You would have to handle this carefully.

You could also start a background thread in the servlet. The background thread
could open a socket to the client and send data when it was ready. The client
would have to be listening to accept the connection and be able to read the
data. But with this method you are at the mercy of the servlet container as it
may decide to unload the servlet if it doesn't received any new service calls.

The simplest method is to use blocking calls. The client makes a service request
to the servlet as normal, but the servlet does not return until there is
something to return. This would presumably require a separate thread in the
client to wait for that service call to return so the main processing of the
client could continue. You would also create one thread per client request in
the servlet, which might also cause problems. However, it requires no
connection from the server back to the client, and maybe your best bet for
getting around the proxy/firewall problem.

> Which leads me back to NIO.  Does it suffer the same problems as RMI?
> Namely, will it play well if the client is behind a proxy?  If so, why is it
> that RMI can't and NIO can?

I have no experience of proxies so can't help here.

Signature

Nigel Wade, System Administrator, Space Plasma Physics Group,
           University of Leicester, Leicester, LE1 7RH, UK
E-mail :    nmw@ion.le.ac.uk
Phone :     +44 (0)116 2523548, Fax : +44 (0)116 2523555

Arne Vajhøj - 12 Dec 2007 02:11 GMT
>> I understand that RMI doesn't play well with the internet because it can't
>> work properly when either the client or the server is behind a proxy unless
[quoted text clipped - 17 lines]
> possible to open only the rmiregistry port and the specific RMI server ports in
> the firewall.

It is possible.

RMISocketFactory.setSocketFactory(new FixedPortRMISocketFactory());
LocateRegistry.createRegistry(60000);

and:

package test.server;

import java.io.IOException;
import java.net.Socket;
import java.net.ServerSocket;
import java.rmi.server.RMISocketFactory;

public class FixedPortRMISocketFactory extends RMISocketFactory {
   private static int socketNumber = 60000;
   public Socket createSocket(String host, int port) throws IOException {
      return new Socket(host, port);
   }
   public ServerSocket createServerSocket(int port) throws IOException {
      if(port == 0) {
          socketNumber++;
          port = socketNumber;
      }
      return new ServerSocket(port);
   }
}

will use port 60000 for registry and 60001, 60002, ... for
server.

>> And I understand that servlets don't have this problem because they
>> communicate through the standard HTTP port but that servlets don't support
[quoted text clipped - 12 lines]
> the client whilst the client is waiting for the servlet to respond to its
> initial request. You would have to handle this carefully.

Servlet containers are not written to support long running servlets.

> You could also start a background thread in the servlet. The background thread
> could open a socket to the client and send data when it was ready. The client
> would have to be listening to accept the connection and be able to read the
> data.

Much better concept.

>      But with this method you are at the mercy of the servlet container as it
> may decide to unload the servlet if it doesn't received any new service calls.

I think that is only theoretical.

> The simplest method is to use blocking calls. The client makes a service request
> to the servlet as normal, but the servlet does not return until there is
> something to return.

I think a non non waiting servlet and a thread is much better.

With many requests the waiting servlets could lockup the container.

> I have no experience of proxies so can't help here.

Piece of cake.

For URLConnection one just set a couple of defines to setup
the proxy server.

With plain sockets one connect to the proxy server and send
the request just with full URL instead of just path.

Arne
Nigel Wade - 12 Dec 2007 11:36 GMT
>>> I understand that RMI doesn't play well with the internet because it can't
>>> work properly when either the client or the server is behind a proxy unless
[quoted text clipped - 67 lines]
>
> Servlet containers are not written to support long running servlets.

"Long" as in "how long is a piece of string" is a relative term... ;-)

>> You could also start a background thread in the servlet. The background thread
>> could open a socket to the client and send data when it was ready. The client
>> would have to be listening to accept the connection and be able to read the
>> data.
>
> Much better concept.

I have tried this specific method and failed. The thread would run perfectly for
anything between 12 to 14 days, and then die without any indication as to why
it had died. There was no output in any of the Tomcat logs, or the servlet
logs, no stack trace, and I was unable to establish any monitor which would
trap the thread's death. It just vanished without a trace. Needless to say, a
thread which runs for 12 to 14 days and then vanishes is rather hard to debug.
So I changed the design to use blocking calls.

In my case the "long" as discussed above is typically of the order of 10s, and I
use a timeout so there is no issue with the container and long running
servlets. Of course this means the client has to handle the problem of a call
returning with no data. But that's a simple matter of having the thread in the
client which reads the data loop over the call, and re-issue it if the return
status indicates a timeout.

>>      But with this method you are at the mercy of the servlet container as it
>> may decide to unload the servlet if it doesn't received any new service calls.
>
> I think that is only theoretical.

Maybe...

>> The simplest method is to use blocking calls. The client makes a service request
>> to the servlet as normal, but the servlet does not return until there is
>> something to return.
>
> I think a non non waiting servlet and a thread is much better.

It would be if it can be made to work. Besides keeping the thread alive, you
have the problem of the servlet being able to establish a connection back to
the client through whatever firewalls are in the way.

> With many requests the waiting servlets could lockup the container.

Yep, all the methods have pros and cons. These need to be weighed up in the
context of how the application will be used in practise. I don't think there is
any "one size fits all" solution to this type of problem.

Signature

Nigel Wade, System Administrator, Space Plasma Physics Group,
           University of Leicester, Leicester, LE1 7RH, UK
E-mail :    nmw@ion.le.ac.uk
Phone :     +44 (0)116 2523548, Fax : +44 (0)116 2523555

Arne Vajhøj - 16 Dec 2007 02:40 GMT
>> Servlet containers are not written to support long running servlets.
>
> "Long" as in "how long is a piece of string" is a relative term... ;-)

Yup. But most web developers have some idea about how long time it
should take to respond to a HTTP requests. Some web servers have
a limit they enforce.

>> Much better concept.
>
[quoted text clipped - 4 lines]
> trap the thread's death. It just vanished without a trace. Needless to say, a
> thread which runs for 12 to 14 days and then vanishes is rather hard to debug.

True.

> In my case the "long" as discussed above is typically of the order of 10s,

10s should be OK. Heavy database queries could take that time. I would
be worried if it was hours or many minutes.

> It would be if it can be made to work. Besides keeping the thread alive, you
> have the problem of the servlet being able to establish a connection back to
> the client through whatever firewalls are in the way.

It could be easier to have the client connect to a port.

Arne
Esmond Pitt - 13 Dec 2007 01:51 GMT
> It is possible.
>
> RMISocketFactory.setSocketFactory(new FixedPortRMISocketFactory());
> LocateRegistry.createRegistry(60000);
[snip]

It is much more possible than that. You don't haev to use socket
factories at all. Just call UnicastRemoteObject.exportObject(Remote
remote, int port), or super(port) if you extend URO.
Qu0ll - 12 Dec 2007 05:23 GMT
Thanks for the info...

> You could also start a background thread in the servlet. The background
> thread
[quoted text clipped - 6 lines]
> may decide to unload the servlet if it doesn't received any new service
> calls.

If I open a socket to the client in a separate thread, how do that thread
know who/where the client is and how does it know when the client is ready
to accept data?  And how does the client know when to respond to accept the
socket connection and when to receive data?  Sorry for the confusion - this
is all very new to me.

Signature

And loving it,

-Q
_________________________________________________
Qu0llSixFour@gmail.com
(Replace the "SixFour" with numbers to email me)

Nigel Wade - 12 Dec 2007 11:48 GMT
> Thanks for the info...
>
[quoted text clipped - 12 lines]
> know who/where the client is and how does it know when the client is ready
> to accept data?  

The client has to be listening before it makes the call to the servlet (or you
need some other synchronization method). The client must tell the servlet where
to connect back to, or the client has to use a fixed port. This needs to be
part of the protocol.

> And how does the client know when to respond to accept the  
> socket connection and when to receive data?  Sorry for the confusion - this
> is all very new to me.

I would expect the client to create a ServerSocket, either on a fixed port or
randomly assigned port. It would need to create a new thread to accept a call
on that Socket and handle the data the servlet thread sends. Then it can then
make a call to the servlet to start the thread, possibly including the port
number for the callback.

Signature

Nigel Wade, System Administrator, Space Plasma Physics Group,
           University of Leicester, Leicester, LE1 7RH, UK
E-mail :    nmw@ion.le.ac.uk
Phone :     +44 (0)116 2523548, Fax : +44 (0)116 2523555

Qu0ll - 12 Dec 2007 12:45 GMT
> The client has to be listening before it makes the call to the servlet (or
> you
[quoted text clipped - 3 lines]
> be
> part of the protocol.

> I would expect the client to create a ServerSocket, either on a fixed port
> or
[quoted text clipped - 5 lines]
> port
> number for the callback.

This may sound like a silly question, but by opening sockets on particular
port(s), aren't we back at square one with respect to firewalls and their
related problems?  This is the key thing I am trying to work around.

Signature

And loving it,

-Q
_________________________________________________
Qu0llSixFour@gmail.com
(Replace the "SixFour" with numbers to email me)

Lew - 12 Dec 2007 15:02 GMT
> This may sound like a silly question, but by opening sockets on
> particular port(s), aren't we back at square one with respect to
> firewalls and their related problems?  This is the key thing I am trying
> to work around.

Yes.  That's one reason why most client-server protocols eschew client
callbacks, plus it's complicated.  Firewalls generally allow return traffic
for outbound clients, but they get finicky about spontaneous inbound traffic.

Signature

Lew

Matt Humphrey - 12 Dec 2007 15:15 GMT
>> This may sound like a silly question, but by opening sockets on
>> particular port(s), aren't we back at square one with respect to
[quoted text clipped - 5 lines]
> traffic for outbound clients, but they get finicky about spontaneous
> inbound traffic.

Where finicky here means that any meaningful firewall will block the
incoming connections by default and NAT routers will completely block the
incoming requests unless forwarding is explicitly allowed.

Matt Humphrey http://www.iviz.com/
Lew - 12 Dec 2007 15:22 GMT
>>> This may sound like a silly question, but by opening sockets on
>>> particular port(s), aren't we back at square one with respect to
[quoted text clipped - 8 lines]
> incoming connections by default and NAT routers will completely block the
> incoming requests unless forwarding is explicitly allowed.

Quite so.

Signature

Lew

Qu0ll - 12 Dec 2007 17:13 GMT
>>> Yes.  That's one reason why most client-server protocols eschew client
>>> callbacks, plus it's complicated.  Firewalls generally allow return
[quoted text clipped - 6 lines]
>
> Quite so.

So basically I am in a no-win situation.  I can have callbacks with RMI but
it doesn't play well with firewalls and I can't have callbacks with any
other method for the same reason.  Quite frankly, if callbacks of any kind
can't be made to work with firewalls then they are useless in a practical
sense given that most/all corporations use firewalls.  So-called "Comet"
approaches looked promising because the callbacks pass through the standard
HTTP port (or that's my understanding) but it seems that they can't be made
to work with applets.  *sigh* Ho hum.

Signature

And loving it,

-Q
_________________________________________________
Qu0llSixFour@gmail.com
(Replace the "SixFour" with numbers to email me)

Matt Humphrey - 12 Dec 2007 18:38 GMT
>>>> Yes.  That's one reason why most client-server protocols eschew client
>>>> callbacks, plus it's complicated.  Firewalls generally allow return
[quoted text clipped - 15 lines]
> standard HTTP port (or that's my understanding) but it seems that they
> can't be made to work with applets.  *sigh* Ho hum.

It's a fundamental characteristic of TCP/IP that listeners cannot not reach
out to callers--they have to wait for the caller to first connect.  Network
topology (NATs & firewalls) has grown up around this concept to the extent
that client-to-server connections are easy and common whereas
server-to-client connections require special configuration. If you want
clients to receive timely (non-polled) events, they must maintain an open
connection to the server.  It is entirely possible to do so, but you have to
keep in mind that you're trading server performance for client performance.

It's not clear to me why servlets would not work for this, even if the
connection is proxied.   The technique I use (with RMI, not HTTP) is that
the client requests "waiting events".  This makes the connection which then
stays open so long as there are no waiting events, but only up to a small
time limit, such as a minute--something well below the servlet container's
threshold.  When an event arrives it either is sent as the reply directly
and the connection closed or it is queued until the next request. (You could
keep the connection open depending on how long "long" is and whether
proxying is a problem.)  The point is that the connection doesn't have to
stay open indefinately.  We're simply trying to beat the latency of polling.
(If the container threshold is low enough there will be little difference
between this and polling and you'll get the worst of both worlds.)

The performance limitation of this technique is that all your clients will
have simultaneously pending waits that are all essentially idle. They will
receive a fast response to any arriving event, but the server will not
support very many clients, hence the tradeoff of client for server
performance.

I plan to try this out soon, as soon as I get Eclipse to work with JBoss
again.

Matt Humphrey http://www.iviz.com/
Nigel Wade - 13 Dec 2007 10:49 GMT
> This may sound like a silly question, but by opening sockets on particular
> port(s), aren't we back at square one with respect to firewalls and their
> related problems?  This is the key thing I am trying to work around.

Yes.

If the server wants to callback to the client the client has to be listening on
some port. The server has to be able to open a socket to that port. If it's a
fixed port you only need to poke one hole in the firewall, if it's a random
port you need to poke a very wide hole. If there is any NAT involved then it
becomes even more complicated. The same applies to any callback mechanism,
whether it's based on RMI, servlets or raw sockets.

This is why a blocking call method might be best. But you need to ascertain
whether it can meet other requirements. Each client waiting for a response will
generate a thread in the servlet, with each thread blocked in the service
routine. The constraints on the servlet/servlet container may not allow that.
If you implement a timeout mechanism to reduce the length of time for which the
servlet blocks (effectively delayed polling) you will inevitably increase the
number of sockets being created/destroyed, and that may cause other problems.

Any method to implement bi-directional asynchronous transfer through firewalls
is complicated. Callback mechanisms are typically used within LANs, between
trusted hosts, where any firewalls are under the the same overall
administrative control.

Signature

Nigel Wade, System Administrator, Space Plasma Physics Group,
           University of Leicester, Leicester, LE1 7RH, UK
E-mail :    nmw@ion.le.ac.uk
Phone :     +44 (0)116 2523548, Fax : +44 (0)116 2523555

Arne Vajhøj - 16 Dec 2007 02:47 GMT
>> You could also start a background thread in the servlet. The
>> background thread
[quoted text clipped - 10 lines]
> thread know who/where the client is and how does it know when the client
> is ready to accept data?

The info comes with the HTTP request and the client start listening
before it sends the HTTP request so it will always be ready when the
server connects.

But for client firewall it may be better to have the clients
connect.

Arne
TwelveEighty - 17 Dec 2007 04:28 GMT
> Thanks for the info...
>
[quoted text clipped - 22 lines]
> Qu0llSixF...@gmail.com
> (Replace the "SixFour" with numbers to email me)

Folks,

Wouldn't a way better design pattern for the OP to use JMS here? If he
is truly looking for async communication originating from possibly any
"node" on a network going to another node, but firewall friendly...?
The "client" would make a request (either through a web service or JMS
message) and then simply wait for messages to show up.
Richard Maher - 17 Dec 2007 21:40 GMT
Hi,

> Wouldn't a way better design pattern for the OP to use JMS here?

Wouldn't better still be a Multicast Socket setup such as outlined in: -
http://groups.google.com/group/comp.lang.java.programmer/msg/ae117827662e8ea5

Whether an unsigned Applet is permitted to read a Multicast message from the
codebase I still don't know, but if you try it and report back that'd be
great :-)

Cheers Richard Maher

> > Thanks for the info...
> >
[quoted text clipped - 30 lines]
> The "client" would make a request (either through a web service or JMS
> message) and then simply wait for messages to show up.
Qu0ll - 20 Dec 2007 04:09 GMT
> Wouldn't better still be a Multicast Socket setup such as outlined in: -
> http://groups.google.com/group/comp.lang.java.programmer/msg/ae117827662e8ea5
[quoted text clipped - 3 lines]
> codebase I still don't know, but if you try it and report back that'd be
> great :-)

Well according to the JSE 6 JavaDocs:

"Currently applets are not allowed to use multicast sockets."

so I guess the answer is no.  And wouldn't this solution still have the
problem with getting through firewalls?

Signature

And loving it,

-Q
_________________________________________________
Qu0llSixFour@gmail.com
(Replace the "SixFour" with numbers to email me)

Richard Maher - 06 Jan 2008 13:27 GMT
Hi Q,

> Well according to the JSE 6 JavaDocs:
>
> "Currently applets are not allowed to use multicast sockets."

Thanks for the pointer. I have to say that I'm a bit curious as to what
exactly "Currently" means in this context. It looks like multicast socket
functionality has been with the Java SDK since 1.1 so maybe it's a bit like
"Currently the sun rises in the east ans sets in the west" :-)

What I did find on the web were references to people who successfully
deployed *signed* applets that use multi-cast sockets. (Along with others
who say it can't be done, and yet others who've altered the security manager
behaviour) My impression is that it works with signed-applets but there's
probably only one sure way to find out.

(Personally, I can't see why an unsigned applet would be breaking any
sandbox rules by *reading* a multicast message eminating from the codebase,
but maybe that's just me?)

>   And wouldn't this solution still have the
> problem with getting through firewalls?

No idea; best ask a firewall guy :-) How they are configured for UDP traffic
and, in the absence of a destination port, how you'd designate a multicast
group address as being "open" is a mystery to me.

Sorry not to be of more help.

Cheers Richard Maher

> > Wouldn't better still be a Multicast Socket setup such as outlined in: -

http://groups.google.com/group/comp.lang.java.programmer/msg/ae117827662e8ea5

> > Whether an unsigned Applet is permitted to read a Multicast message from
> > the
[quoted text clipped - 7 lines]
> so I guess the answer is no.  And wouldn't this solution still have the
> problem with getting through firewalls?


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.