I have been trying to implement some basic push functionality with primefaces in jsf. I have used there counter example http://www.primefaces.org/showcase-labs/push/counter.jsf. Essentially its a button that increments a shared counter. When running this example I always get this error:
ERROR: MAC did not verify!
My understanding is that a mac is generated every session and then checked upon each incoming message to verify that the source hasn't changed (I think). I have not been able to find the cause of this and have looked at other threads such as:
ERROR: MAC did not verify! PrimeFaces
JSF: Mojarra 2.1 to 2.2 migration causing ViewExpiredException
Unfortunately these haven't solved my problem. Both seem to be caused by a ViewExpiredException which I am not getting. The only thing that I have found to stop it is to change the state saving method from client to server in web.xml:
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
However when doing this the counter is no longer shared but appears to be per user, which is not what I want. My ultimate goal is to implement a chatroom, which for the most part is there but right now it using short polling which is not very scalable. Having looked at primefaces push I thought it would be ideal but have been struggling to use it.
I have tried on multiple web servers (Tomcat, Jetty and Glassfish) and have tried using different versions of JSF (Mojarra) and versions of primefaces (3.4 and 4.0). I have tested it across multiple browsers and on multiple computers. Sometimes I can increment the counter a few times before I get the error, sometimes it happens straight away. I get no exceptions or servere errors and everything compiles. I'd also like to mention that I have had this error before on other projects, but it has gone away after restarting the server. When using primefaces push it always occurs. Any help will be appreciated.
EDIT
When leaving state saving to server in web.xml to avoid MAC Error, I have noticed that the shared counter works in a per browser basis from the same machine. Meaning if I have multiple tabs or windows, updating the counter in one updates in all of them. But it doesn't work across browsers, a change in the counter in firefox is not reflected in chrome or IE, or the other ways round. It is also not reflected if on two separate computers. I don't know if this helps, but thought I would mention it.
EDIT
After noticing that the bean in the example is session scoped I changed it to application scoped. Of course session scoped means every browser has their own copy. Now the changes are reflected across browser and machines. Back to my original problem, I would still like to know why changing the saving state to server fixes the MAC error, and what the implications of this are ? I assume that the server now has to maintain view states for each session rather than the client, less scalable/more client-server traffic ? From what I've read if you set the saving state to server you can't check for view expired exceptions or stop users from creating views if they already have too many, is this correct ?
Seems your application have dependency problem ViewExpiredException can be handled easily, it is a no problem handle ViewExpiredException
full configured JSF project example JSF2.2 frontend
ByteArrayGuard class randomly outputs "ERROR: MAC did not verify!" messages to the error console. This only occurs when client side viewstate encryption is enabled and that multiple clients are running against the server.
So you must change that class in your Java Server Faces references with...
And reload this jar. JSF_REFERENCE