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.
WebSocket integration by Arjan Tijms
JSF 2.3 - Explicitly open/close a websocket channel
JSF 2.3 - Conditionally open/close a websocket channel
JSF 2.3 - Multiple File Upload with HTML 5, AJAX and upload progress bar via web sockets
JSF 2.3 - Conditionally open/close a websocket channel
JSF 2.3 - Multiple File Upload with HTML 5, AJAX and upload progress bar via web sockets
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.
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