Java EE 6 server push
Background
I'm well into building a central appointment booking system for various service providers. This is being built on Java EE 6 on GlassFish 3.1.1, making use of JSF 2, EJB 3.1 and other JEE6 standards. Each service provider has their own appointment booking facility running on their own server that is connected to the Internet, but currently they don't have any interface to allow their patients to make their own appointments.
My system will synchronously book appointments on service providers' systems (in response to user requests) via an API I have defined which involves streaming XML over HTTP. These appointment booking requests are synchronous because service providers will continue to book appointments directly in their system the old fashioned way (over the phone/counter) and, for whatever reasons, their system reserves the right to reject such requests (to prevent double bookings and for other reasons). So, their systems retain the status of being the source of truth.
For obvious reasons (mainly security), API connections are established by the service providers' systems. This means requests are being sent by the server (my system) and responses by the client (their system).
Problem
I need some suggestions regarding how I can build a server-push XML over HTTP API using Java EE 6 on GlassFish 3.1.1. A number of less than ideal options come to mind. One of them involves a singleton bean that contains a map of my appointment IDs to their appointment booking responses. In this scenario, my system polls the map for a limited time (up to 10 seconds, for example) until it finds a matching response, then returns the response which is then handled eventually in the JSF UI. Meanwhile, the API servlet (or perhaps JAX-RS web service) polls the singleton bean for requests, converts them to XML and streams them to the service provider's output stream.
I'm sure there must be a number of better ways of doing this not involving thread-per-connection, blocking, polling, etc.
Ideas?
Update
I was leaning towards Atmosphere/Jersey, but now I realize that blocking I/O is quite scalable under NPTL, so I'm flexible in that regard.
Here's how I did it:
Start with a singleton EJB containing:
Map<Long, BlockingDeque<OutboundApiMessage>>
, where the key is the API client ID; Map<Long, Exchanger<AppointmentExchange>>
, where the key is the web-side appointment ID and AppointmentExchange
contains that ID and the API client side appointment ID. I set bean managed concurrency control on the singleton EJB, defined some methods to enqueue, dequeue and requeue (the latter in case server push of the OutboundApiMessage
failed and needed to be added to the front of the queue where it would be the next item to be dequeued), wired it to the JAX-RS web services (one for upstream, one for downstream).
The singleton EJB has a method to synchronously book an appointment. It enqueues a message to be picked up by the client, creates an Exchanger
containing a new AppointmentExchange
instance then blocks waiting for the exchange. When an answer comes back on the inbound web service, that web service notifies the singleton EJB via another method which performs the exchange via the Exchanger
.
It all works quite well now. Of course, there is a bit more to it than that, but that's the gist of it.
链接地址: http://www.djcxy.com/p/76472.html上一篇: 用post方法卷曲
下一篇: Java EE 6服务器推送