My JSF Books/Videos My JSF Tutorials OmniFaces/JSF PPTs
JSF 2.3 Tutorial
JSF Caching Tutorial
JSF Navigation Tutorial
JSF Scopes Tutorial
JSF Page Author Beginner's Guide
OmniFaces 2.3 Tutorial Examples
OmniFaces 2.2 Tutorial Examples
JSF Events Tutorial
OmniFaces Callbacks Usages
JSF State Tutorial
JSF and Design Patterns
JSF 2.3 New Features (2.3-m04)
Introduction to OmniFaces
25+ Reasons to use OmniFaces in JSF
OmniFaces Validators
OmniFaces Converters
JSF Design Patterns
Mastering OmniFaces
Reusable and less-verbose JSF code

My JSF Resources ...

Java EE Guardian
Member of JCG Program
Member MVB DZone
Blog curated on ZEEF
OmniFaces is an utility library for JSF, including PrimeFaces, RichFaces, ICEfaces ...

[OmniFaces Utilities] - Find the right JSF OmniFaces 2 utilities methods/functions

Search on blog

Petition by Java EE Guardians

Twitter

luni, 28 martie 2016

JSF 2.3 - Firing one-time push when the web socket channel has been opened

Read also:

WebSocket integration by Arjan Tijms


In this post, we want to write an application that uses a web socket to "say" Hello world! - pushes the Hello World! message to a channel named hello. This should take place automatically (when the channel has been opened) and one-time only.

Since a web socket channel is automatically opened, we don't need to put any effort in this step. We just define in page a simple web socket like below:

<f:websocket channel="hello" onmessage="socketListener" /> 

Note: In such cases, we should use this together with the optional user attribute of  <f:websocket/> to push the message to a specific user that it is login. Moreover, we can use the optional scope attribute set to session (push messages to all views in the current user session only) or view (push messages to  to the current view only). In such cases, the CDI managed bean should be annotated with the CDI @SessionScoped respectively @ViewScoped. Since we just want to show the technique of  firing one-time push when the web socket channel has been opened, we will not "pollute" the code and we will use the application scope.

Since this channel should "transport" a single message, we need to close the channel after receiving the first message, like below:

<div id="helloId"></div>

<script type="text/javascript">           
 function socketListener(message, channel, event) {               
  document.getElementById("helloId").innerHTML = message;           
  jsf.push.close("hello");
 }
</script>

Further, we have an application bean capable to push the message to hello channel:

@Named
@ApplicationScoped
public class PushBean implements Serializable {

 @Inject
 @Push(channel = "hello")
 private PushContext push;

 public void pushAction() {
  push.send("Hello world!");
 }
}

The only aspect that we didn't cover so far refers to pushing the message automatically when the channel has been opened. For this, we can use two server events:

CDI WebsocketEvent will be fired with @WebsocketEvent.Opened qualifier
This event is fired when a web socket channel has been opened.

CDI WebsocketEvent will be fired with @WebsocketEvent.Closed qualifier
This event is fired when a web socket channel has been closed.

Both events can be observed in an application scoped CDI bean as below. So, in our case we can take advantage of the event fired when the web socket channel has been opened and push the Hello world! message:

@ApplicationScoped
public class WebsocketObserver {
   
 private static final Logger LOG =  
                Logger.getLogger(WebsocketObserver.class.getName());       
   
 @Inject   
 private PushBean pushBean;

  public void onOpen(@Observes @Opened WebsocketEvent event) {        
  pushBean.pushAction();       
 }   
   
 public void onClose(@Observes @Closed WebsocketEvent event) {
  String channel = event.getChannel();
  LOG.log(Level.INFO, "Channel {0} was successfully closed!", channel);
 }
}

Notice that via the WebsocketEvent object we can obtain information such as:

Returns a string representing the <f:websocket/> channel name:
event.getChannel();         

Returns a string representing the <f:websocket/> user:
event.getUser();            


Returns a CloseCode instance representing the close reason code:
event.getCloseCode();      

Now, our application output will be like in figure below:


The complete application is available here.

Niciun comentariu :

Trimiteți un comentariu

JSF BOOKS COLLECTION

Postări populare

Follow by Email

Visitors Starting 4 September 2015

Locations of Site Visitors