-
Notifications
You must be signed in to change notification settings - Fork 113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WSS protocol errors #69
Comments
Looks like the SSL library is doing something wrong. Could you show how you are using it? |
@jaspervdj, sure and thanks! Not trying to hijack this issue but a few exceptions occur whenever an authenticated user either refreshes or closes their browser window. So maybe we could go through those as well :) before we get to
[10/Jun/2014:22:04:12 +0000] ["192.168.50.1"]: an exception escaped to toplevel:
ConnectionAbruptlyTerminated
[10/Jun/2014:22:08:56 +0000] ["192.168.50.1"]: an exception escaped to toplevel:
ServerAppDone I saw this issue: jaspervdj/websockets-snap#9, which deals with the -- Initial handshake is made
handleWebSox :: Handler App (AuthManager App) ()
handleWebSox = currentUserId >>= maybe the404 handleUser
where
handleUser uid = do
Just status <- queryDB (GetUserStatus uid)
mvar <- withTop' id $ view websox
when status $ WS.runWebSocketsSnap $ \pendingConn ->
do let start = WS.acceptRequest pendingConn
cleanup conn = WS.sendClose conn (BrowserClose uid)
action = application mvar
bracket start cleanup action In regards to the Here's all of it, if there's anything glaringly wrong I'd appreciate your feedback. Otherwise I'm not sure how the exception is escaping (after it's been caught). Unless there are multiple exceptions occurring at different layers. -- | Types
type WSClients = I.IntMap WS.Connection
-- | Helper Functions
addConnection :: UID -> WS.Connection -> MVar WSClients -> IO ()
addConnection uid conn mvar =
modifyMVar_ mvar $ \connections ->
return (I.insert uid conn connections)
removeConnection :: UID -> MVar WSClients -> IO ()
removeConnection uid mvar =
modifyMVar_ mvar $ \connections ->
return (I.delete uid connections)
getConnection :: UID -> MVar WSClients -> IO (Maybe WS.Connection)
getConnection uid mvar =
do result <- tryReadMVar mvar
return $ case result of
Just conns -> I.lookup uid conns
Nothing -> Nothing
-- | Add/Remove browser connection to IntMap
application :: MVar WSClients -> WS.Connection -> IO ()
application mvar conn = do
cmd <- WS.receiveData conn :: IO Command
case cmd of
BrowserClose uid -> removeConnection uid mvar
BrowserConnect uid ->
catch (handleConnection uid conn mvar) $ \(e :: SomeException) ->
do case fromException e of
Just WS.ConnectionClosed -> do putStrLn "caught conn closed"
removeConnection uid mvar
_ -> print (e, "oh no :(") >> removeConnection uid mvar
-- | Block until data is received
handleConnection :: UID -> WS.Connection -> MVar WSClients -> IO ()
handleConnection uid conn mvar = do
addConnection uid conn mvar
forever $ do
msg <- WS.receiveData conn
case msg of
cmd@UnknownCommand{..} -> return ()
cmd -> sendMsg cmd mvar
-- | Push any WebSocket message to the client
sendMsg :: Command -> MVar WSClients -> IO ()
sendMsg cmd mvar = do
result <- getConnection (uid cmd) mvar
forM_ result $ \conn -> WS.sendTextData conn $ wsxMsg cmd I think the |
Think I narrowed down the The -- Worker POSTs to Web Server here, send websocket notifications to client
workerUpdates :: Handler App App ()
workerUpdates = method POST handlePOST
where handlePOST = do
Just cmd <- getJSON
mvar <- view websox
io $ sendMsg cmd mvar -- I should be using a `try` here -- | Push any WebSocket message to the client
sendMsg :: Command -> MVar WSClients -> IO ()
sendMsg cmd mvar = do
result <- getConnection (uid cmd) mvar
forM_ result $ \conn -> WS.sendTextData conn $ wsxMsg cmd |
Ok I'm dumb. |
|
Ok, kind of embarrassing, but I wasn't closing the websocket connection on the client Adding the var ws = new WebSocket('wss://' + window.location.hostname + '/websox/');
window.onbeforeunload = function() {
console.log('closing websocket');
if (ws) ws.close();
}; Sadly, -- Initial handshake is made
handleWebSox :: Handler App (AuthManager App) ()
handleWebSox = currentUserId >>= maybe the404 handleUser
where
handleUser uid = do
Just status <- queryDB (GetUserStatus uid)
mvar <- withTop' id $ view websox
when status $ do
MIO.catch (handleWebSockets mvar uid) $ \(e :: SomeException) ->
io $ case show e of
"ServerAppDone" -> putStrLn "Caught ya!" -- <-- never caught
other -> print ("caught another one", other)
handleWebSockets mvar uid = do
WS.runWebSocketsSnap $ \pendingConn ->
do let start = WS.acceptRequest pendingConn
cleanup conn = WS.sendClose conn (BrowserClose uid)
action conn = application mvar conn
bracket start cleanup action
return () I'm excited for Snap 1.0 where monad-control can be used for the base monad. Hopefully enclosed-exceptions can be used to catch all exceptions like these. Any idea what the performance implications of exceptions that escape to the top-level are like? |
Your Exceptions escaping to the top-level are reasonably cheap, I think the logging overhead is pretty much to the only factor to take into account there. |
Yea |
Left ProtocolError "error:140D00CF:SSL routines:SSL_write:protocol is shutdown"
I get this error intermittently. I'm using http-streams to post to a snap-server which reads a websocket connection and sends data to the client. Having trouble tracking down the exact origin of the error. Wondering if anyone else has seen this.
The text was updated successfully, but these errors were encountered: