It's in 0.8, which has actually just shipped. I will post more tomorrow, just finished pushing all the packages out and it's late here. The short version is you can do this to connect to Salesforce (I've actually done this, but not created any PushTopics, just made sure I can connect):
token = get_salesforce_token
client.set_header 'Authorization', "OAuth #{token}"
client.bind 'transport:down' do
token = get_salesforce_token
client.set_header 'Authorization', "OAuth #{token}"
end
This ought to do what you want, in that it will catch when the client disconnects and reset the token. It is not ideal, for reasons I'll get into, but it's a start and the 0.8 release was already plenty big enough and I've been trying to ship it for weeks. If this doesn't work we'll do bug fix releases.
The reason I'm not entirely happy with this is that it doesn't give you specific enough access to what Salesforce does with HTTP to catch the error robustly. I *ought* to work, by dint of the fact that a request that does not return JSON will trigger transport:down, but that's kind of a blunt instrument in this case. When you're not authenticated, Salesforce send a 4xx response containing HTML.
This is problematic for several reasons that would impact any attempt to provide sensible APIs in Faye for dealing with this.
First, their OAuth only accepts tokens in the header (rather than a query string, in violation of the OAuth spec), and ability to set headers is transport-dependent (e.g. callback-polling and websocket transports cannot do this; fortunately Salesforce only supports long-polling. I already don't like the Faye setHeader() method for this reason: it makes transport details leak out of the client interface.
Second, in the case of en error they do not respond in a way that a Bayeux client knows how to deal with: instead of sending a /meta/handshake response with an error field, they send a 4xx status code containing HTML. This makes the response literally unreadable by certain transports, and even for transports that can read it, they don't understand arbitrary HTML that is clearly meant for human consumption.
So what I'm saying is, this raises interesting questions about what parts of Faye would need to be made pluggable in order to handle this robustly. Does the long-polling transport need to understand non-200 responses, and emit errors containing the response text? Does the user need to be able to completely replace the long-polling transport? Should setHeader() throw an error if the underlying transport does not support it? Does transport selection need to accept user-defined predicates (for example because header-setting cannot be feature detected, the knowledge of that requirement must be encoded in the library or left to users to plug in). This is probably not an exhaustive list.
I hope what we have in 0.8 will fix your problem, and like I said bug fixes will be released to best handle this with the current feature set. The question then remains: are all the questions above important enough that additional work is needed to support servers with slightly esoteric requirements?