I'm trying to make websockets work with servant-server:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators #-}
import Control.Monad.IO.Class
import Data.Text (Text)
import Network.Wai.Handler.Warp (run)
import Network.WebSockets
import Servant hiding (route)
import Servant.API.WebSocket
type API = Raw
:<|> "game" :> WebSocketPending
myAPI :: Proxy API
myAPI = Proxy
server :: Server API
server = serveDirectoryFileServer "site"
:<|> game "From socket server"
game :: MonadIO m => Text -> PendingConnection -> m ()
game msg pending = do
conn <- liftIO $ acceptRequest pending
liftIO $ sendTextData conn msg
app :: Application
app = serve myAPI server
main :: IO ()
main = run 8080 app
The intention is to send a string From socket server back to a client for testing.
In Firefox console:
// Create WebSocket connection.
socket = new WebSocket('ws://localhost:8080/game');
// Connection opened
socket.addEventListener('open', function (event) {
socket.send('Hello Server!');
});
// Listen for messages
socket.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
});
I got an error frome firefox:
Firefox can’t establish a connection to the server at ws://localhost:8080/game
Could someone give me a hint?
Update:
Here's the code that worked after re-ordering the API.
type API = "game" :> WebSocketPending
:<|> Raw
myAPI :: Proxy API
myAPI = Proxy
server :: Server API
server = game
:<|> serveDirectoryFileServer "site"
game :: MonadIO m => PendingConnection -> m ()
game pending = do
conn <- liftIO $ acceptRequest pending
liftIO $ withPingThread conn 30 (return ()) $ do
forever $ do
msg <- receiveData conn :: IO Text
sendTextData conn msg