The current form for message post is something like:
<FORM METHOD="POST"
  ENCTYPE="application/x-www-form-urlencoded"
  NAME="formcbox">
(stuff)
<a name='chatbox'></a>
<small><input type="hidden" name="op" value="message"><br /></small>
<INPUT TYPE="text" NAME="message"  SIZE=15 MAXLENGTH=255>
<INPUT TYPE="submit" NAME="message_send" VALUE="talk">
</FORM>
(please note - double quotes should be used for <a name='chatbox'></a>

Insert a random value (or sequential) in a hidden form tag. This is not overly important. This number is re-generated each page load. Thus, the form is:

<FORM METHOD="POST"
  ENCTYPE="application/x-www-form-urlencoded"
  NAME="formcbox">
(stuff)
<a name='chatbox'></a>
<small><input type="hidden" name="op" value="message"><br /></small>
<INPUT TYPE="hidden" NAME="magic" value="42">
<INPUT TYPE="text" NAME="message"  SIZE=15 MAXLENGTH=255>
<INPUT TYPE="submit" NAME="message_send" VALUE="talk">
</FORM>

In the message table, the magic number would be inserted too. This value must be unique within the table. If someone reloads the page then the same magic number is submitted. The second time, it would be rejected.

This does pose several problems:

  • Other clients would need to have this magic number submission
  • Doesn't let people hit the 'back' button and possibly send a different message if there was a typo to be corrected.

A better solution is to actually put in the message table a constraint around the person/message combination so that it must be unique.

Assume:

Name         Null?    Type
------------ -------- ----------------------------
USER         NOT NULL number
MESSAGE      NOT NULL varchar(255)
TIMESTAMP    NOT NULL datetime
In this case, a unique index (its a small enough table that gets cleaned regularly) is placed on the user/message rows:
CREATE UNIQUE INDEX no_chatbox_dups ON chatbox_tab
    ( USER, MESSAGE )
Thus, any insertion of the same user/message information will come back with the error "cannot insert duplicate value into table" which would then need to be handled properly by perl (in this case, silently fail).

Note: this takes advantage of the regular cleansing of the chatterbox by other processes that roll messages out of the table.


Session cookies and a hash work for almost every case - people use browsers in the vast majority of cases for chatting on edev. However, there are a few distinct times when this would not work.

With the current wave of E2 clients (and the existing ones that are already exist such as the java chatterbox), not ever client that can send a cookie can properly receive a cookie. Thus, sending the "hash of last message" id to the java chatterbox (or a perl command line chatterbox poster, or the #everything chatterbot relay) will not be picked up. The next message would send out the same cookie as it did before without any such hash.

Requiring this part of the cookie would meet with some resistance for much the same reason the "magic" value did - far too much work on the client side to properly pick up and interpret the information.

Furthermore, there is no 'time-limit' on this session cookie. Consider a person trying to say something when the chatterbox is dead silent.

<m_turner> Hello? Anyone out there?
(5 min pass, the chatterbox is clear again)
<m_turner> Hello? Anyone out there?

In my (probably not so humble opinion) the best solution is one that of the unique constraint upon the chatterbox table itself which is then completely done on the database side without any requirements for how the information got there.