Open henrylaxen opened 9 years ago
An Ord
instance would be nice too. It's nice to use a Set
to track the connections so you can easily add/remove.
This can't currently be done in a way that doesn't break backwards compatibility (i.e. introduce some custom monad to track the unique supply), because Connection
can't simply derive Eq
.
You could use some global-supply hack such as
import Control.Concurrent.MVar
import Control.Concurrent.Supply (Supply)
import qualified Control.Concurrent.Supply as Supply
globalSupply :: MVar Supply
globalSupply = unsafePerformIO (Supply.newSupply >>= newMVar)
{-# NOINLINE globalSupply #-}
freshId :: IO Int
freshId = modifyMVar supply (\s ->
let (n, s') = Supply.freshId s
in pure (s', n))
data Connection = Connection
{ ...
, connectionId :: Int
}
Socket
actually provides an Eq
instance so it might be able to piggyback on top of that.
Alternatively, we can use the 4-tuple (source IP, source port, destination IP, destination port)
to uniquely identify the connection as well, but we'd also need to store that info in the Connection
datatype. This would be my preferred solution.
Just to be clear, does this mean that with the current state of WebSockets
, we're just supposed to trust connections? Is there anyway to uniquely identify users right now?
The correct way to do this is to have the server pass the socket 4-tuples to the websockets
library, and then make these available in PendingConnection
/Connection
. However, some of the Haskell HTTP servers do not support that, so I didn't go through with that implementation for now.
I don't really know what you mean by "trust the connections" though. Users should be identified by implementing proper authentication either over HTTPS or through WebSocket messages.
I guess one pattern is to provide a nonce-style token to the user via http, and then identify the websocket connection based on what token they send over.
Well, usually WebSocket apps are part of larger HTTP apps, which already have some sort of authentication system in place using cookies/headers.
Since a WebSocket connection starts out like a normal HTTP request, a great pattern is to use your existing HTTP authentication layer to check the cookies before turning it into a WebSocket connection. This is possible with both the Snap and Yesod backends, and I've personally used this pattern successfully in the past.
Dear Jasper,
I don't know if it is possible, but I think it would be really nice to have an Eq instance of Connection. That way I could have [Connection] and be able to move them to different lists based on some test. I'm working around it now by wrapping Connection and using Data.Supply to generate my own Eq instance. Just something to think about in your copious spare time ;-)