Personally, I prefer the Session bean approach where a Session Facade (ala "Core J2EE Patterns") wraps a special layer of helper objects that manage your legacy system communication.
Now, that's fairly easy to do. So long as your communication is synchronous it presents no problems (that is you send a request down a socket, turn around and wait for the response, and time out if you don't receive one).
However, asynchrounous communication is more problematic. There you have to do some nasty tricks like for instance implementing "bridges" between an asynchronous listener on your socket and a JMS queue (listen on the socket, when you get a request, pop it on a queue and then have an MDB waiting on that queue). Another trick is to simply put the asynchronous listener in the
Servlet engine (web container) rather than in the EJB container.
However, your best bet is to see if it's at all possible to lose the existing TCP/IP infrastructure and see if you can't move to something like JCA. There are now JCA connectors for a number of different types of system -- the days of people writing their own middleware layers are numbered. One thing I would NOT recommend, btw, is trying to write your own JCA layer on top of an existing structure -- writing JCA connectors is a tricky business best left to vendors if at all possible.
Kyle
[ March 26, 2002: Message edited by: Kyle Brown ]