Use setTimeout to detect timeouts rather than Date arithmetic

The values provided by `Date` are subject to system clock skew and manipulation
from testing frameworks that override native APIs. So instead of detecting
timeouts in a setInterval callback that computes the difference of two Date
objects, use setTimeout to start a timeout countdown that is reset whenever the
a message is received.