I observe a strange behavoir for cdi events:
Given the following scenario: An action on the admin page shall update the view of web page news.xhtml (via omnifaces) by adding the value for "Event-Id":
Both beans are session scoped backing beans for their jsf based web pages.
What happens: There are two instances of NewsBean due to two browser windows accessing news.xhtml. When an event is fired, both browser windows are updated. However, both updates come from the @Observes-method of the first instance of NewsBean.
More precisely: NewsBean has a property "id" that is initialized @PostConstruct with a random number. This id is displayed on news.xhtml as "Property-Id" (cf. image). The id is also pushed by the @Observes-method of the bean and displayed on news.xhtml as "Event-Id":
private void onBreakingNews(@Observes Info info) {
channel.send(id); // displayed as "Event-Id" on news.xhtml
}
Let the id's for the two instances simply be 1 and 2. Before the update, browser windows for news.xhtml display:
Browser 1: Browser 2:
Property-Id: 1 Property-Id: 2
Event-Id: Event-Id:
After the update (Event-Id value added):
Browser 1: Browser 2:
Property-Id: 1 Property-Id: 2
Event-Id: 1 Event-Id: 1
That means:
- both instances of NewsBean observed the event and updated their associated browser window
- but the data send to the two browsers comes from the @Observes-method of the first instance
I had expected that each instance's own @Observes-method would be called.
Q1: Is this behavoir intended ?
Q2: Is the @Observes-method allowed to use internal state of the bean instance ? (in this case it would be a bug)
As cdi container I used Weld from WildFly 11. Code for NewsBean is:
@Named @SessionScoped
public class NewsBean {
private int id;
@Inject @Push(channel="pushChannel") private PushContext channel;
private void onBreakingNews(@Observes Info info) {
// channel.send(info.getMsg());
channel.send(id);
}
@PostConstruct
private void init() {
id = new Random().nextInt(100);
}
... getter and setter for id ...
}
Code of news.xhtml:
<h:head>
<f:verbatim>
<script type="text/javascript">
function socketListener(message, channel, event) {
document.getElementById("formId:info").value = message;
};
</script>
</f:verbatim>
</h:head>
<h:body>
<h:outputText value="Property-Id: "/>
<h:outputText value="#{newsBean.id}"/>
<p></p>
<h:form id="formId">
<h:outputText value="Event-Id: "/>
<h:inputText value="" id="info" readonly="true"/>
<o:socket channel="pushChannel" onmessage="socketListener"/>
</h:form>
</h:body>

channelsare proliferating the change to all those views - Siliarus