ADF 12c: Using WebSockets to implement client to client push (in a scalable manner)

0

WebLogic 12c (12.1.2) has support for WebSockets. ADF 12c runs on WebLogic 12c. Therefore, we should be able to leverage that WebSockets support in an ADF application. And indeed we can, as this article describes. It will explain the creation of a simple application – the SlidePresenter – that allows users to select an image from a carousel. As soon as they make the selection, all currently connected clients are synchronized, showing the same slide:

image

The application uses a WebSocket endpoint – an object that acts as the server end for web socket connections. Each browser session connects to the end point and starts a new websocket connection. Whenever a slide is selected, the WebSocket endpoint is informed (on the server side) and broadcasts the slide selection to all connected clients. A brief demo of what this looks like is shown here:

Pushy in Sockets – demo

The application also support an automatic slideshow: one user starts the slideshow by pushing a button. This causes a scheduled future to be instantiated in the server that fires every 3 seconds to advance the slideshow. After two minutes, the show will finish.

The application can be downloaded under Resources. It runs in JDeveloper 12.1.2 on the integrated WebLogic Server.

Steps for creating this application:

1. Create a new ADF Fusion Web Application.

 

2. Add the WebLogic 12.1 API library to the ViewController project (it contains the WebSocket related objects)

image

 

3. Create a JavaScript library with the basic WebSocket plumbing (note: the contents of this library is more or less standard across browsers and across WebSocket server implementation)

image

The JavaScript connects to the websocket endpoint, defined somewhat crudely as “”ws://” + “127.0.0.1:7101/PushyOnSockets-ViewController-context-root”+ “/mediatorendpoint”;” The last part – /mediatorendpoint – corresponds with the pathPattern defined in the WebSocket end point class. When a message is received on the websocket connection, the onMessage function is invoked and subsequently the handleMessage function is invoked. This function checks for messages that start with IMAGE=. When such a message arrives it is interpreted as a slideselection. JavaScript function showPopup is called, passing the selected image as parameter.

 

4. Create the WebSocket endpoint – the Java Class that acts as a WebSocket server

The class SocketMediator extends WebSocketAdapter (that in turn implements WebSocketListener). The annotation

@WebSocket(pathPatterns={“/mediatorendpoint/*”})

is added to have the WebLogic container create a WebSocket endpoint – accessible at ws://host:port//web-context-root/mediatorendpoint .

The class implements several methods – onOpen, onMessage – but the only one that matters for this example is the broadcast method. This method is invoked with a string and will go on to send that string as message to all WebSocket clients that currently have open connections with the server:

image

This method is used to broadcast the slide selection.

 

5. Create the ImageManager class

This class is the brains of the applications. It contains a list of the images to be presented, it handles slide selection events (and broadcasts them through the SocketMediator) as well as start-slide-show-events.

image

 

6. Create the JSF page – as a facelet for example

It has some simple layout components – including the carousel for the images and the popup window to display the selected slide:

image

When an image is selected in the carousel, the clientListener fires and invokes the selectImage JavaScript function.

This function:

image

Sends an event to the server. The event is called processImageSelectEvent and it is processed by a serverListener on the carousel. This listener is associated with the processImageSelection method on the ImageManager bean that we saw before. The name of the selected image is taken from the clientAttribute imageSource and passed as payload in the server event.

When the image selection is broadcast on the WebSocket connections, it ends up in the JavaScript function handleMessage that will invoke showPopup when the WebSocket message starts with IMAGE=. The showPopup function

image

locates the popup, sets the source of the image component and brings up the popup.

The button to start the slideshow:

image

When the button is pressed, the JavaScript function startSlideShow is invoked. This function:

image

sends a server event through/to the serverListener defined on the button that is associated with the slideShow method on the ImageManager bean. This method creates the Scheduled Future that will start after 3 seconds, change the slide selection every three seconds and stop after 2 minutes.

Note: the JavaScript library is added to the page like this:

image

 

7. Add the images to the application:

image

 

8. Run the application.

Open the application in multiple browser clients. Select a slide in one browser and see it popping up in the other browsers. Start the slideshow and see all slides popping up in all browser windows, perfectly synchronized. Notice that there is no hourglass or ever present load indication on your tab. WebSocket is true background, asynchronous interaction, independent of HTTP connections between browser and server.

image

Resources

Download JDeveloper 12.1.2 Application: PushyOnSockets.

Oracle Documentation: Using WebSockets in WebLogic Server – http://docs.oracle.com/middleware/1212/wls/WLPRG/websockets_sse.htm

Share.

About Author

Lucas Jellema, active in IT (and with Oracle) since 1994. Oracle ACE Director for Fusion Middleware. Consultant, trainer and instructor on diverse areas including Oracle Database (SQL & PLSQL), Service Oriented Architecture, BPM, ADF, Java in various shapes and forms and many other things. Author of the Oracle Press book: Oracle SOA Suite 11g Handbook. Frequent presenter on conferences such as JavaOne, Oracle OpenWorld, ODTUG Kaleidoscope, Devoxx and OBUG. Presenter for Oracle University Celebrity specials.

Leave a Reply