2016-01-05 19 views
8

Sto lavorando su Suave 1.0 + Angular 2.0 sample app e molto interessante avviare il server Suave in modalità orologio, quindi il file di visualizzazione del server cambia (js, css, html) nella cartella principale e nelle sottocartelle e invia automaticamente refresh comando a tutte le schede del browser aperte con la mia applicazione quando viene modificato un file.Suave in modalità orologio (durante lo sviluppo)

lite-server da Angular 2 5min Quckstark può fare questo ed è molto utile.

Penso che la maggior parte dei pezzi di orologio può essere trovata in latest Steffen Forkmann's post ma non è molto pulito come inviare refresh alle schede aperte del browser.

Fornire il codice completo dell'implementazione simile con Suave.

risposta

11

Il codice di Suave Server dovrebbe apparire simile a questo

#r "packages/Suave/lib/net40/suave.dll" 
#r "packages/FAKE/tools/FakeLib.dll" 

open Fake 
open Suave 
open Suave.Operators 
open Suave.Sockets.Control 
open Suave.WebSocket 
open Suave.Utils 
open Suave.Files 
open Suave.RequestErrors 
open Suave.Filters 
open System 
open System.Net 


let port = 
    let rec findPort port = 
     let portIsTaken = 
      System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners() 
      |> Seq.exists (fun x -> x.Port = int(port)) 
     if portIsTaken then findPort (port + 1us) else port 
    findPort 8083us 

let logger = Logging.Loggers.ConsoleWindowLogger Logging.LogLevel.Verbose 

let refreshEvent = new Event<_>() 

let handleWatcherEvents (events:FileChange seq) = 
    for e in events do 
     let fi = fileInfo e.FullPath 
     traceImportant <| sprintf "%s was changed." fi.Name 
    refreshEvent.Trigger() 

let socketHandler (webSocket : WebSocket) = 
    fun cx -> socket { 
    while true do 
     let! refreshed = 
     Control.Async.AwaitEvent(refreshEvent.Publish) 
     |> Suave.Sockets.SocketOp.ofAsync 
     do! webSocket.send Text (ASCII.bytes "refreshed") true 
    } 

let cfg = 
    { defaultConfig with 
     homeFolder = Some (__SOURCE_DIRECTORY__) 
     bindings = 
     [ HttpBinding.mk HTTP IPAddress.Loopback port ] 
     listenTimeout = TimeSpan.FromMilliseconds 3000. } 

let app : WebPart = 
    choose [ 
    Filters.log logger logFormat >=> never 
    Filters.path "/websocket" >=> handShake socketHandler 
    Filters.GET >=> Filters.path "/" >=> file "index.html" 
    Writers.setHeader "Cache-Control" "no-cache, no-store, must-revalidate" 
     >=> Writers.setHeader "Pragma" "no-cache" 
     >=> Writers.setHeader "Expires" "0" 
     >=> browseHome 
    NOT_FOUND "Found no handlers." 
    ] 


let watcher = 
    !! ("app/*.js") 
     ++ ("*.html") 
    |> WatchChanges handleWatcherEvents 

try 
    System.Diagnostics.Process.Start(sprintf "http://localhost:%d/index.html" port) |> ignore 
    startWebServer cfg app 
finally 
    watcher.Dispose() 

Così abbiamo impostato osservatore che gestiscono i cambiamenti in js (generato dal dattiloscritto) e html file e inviare refresh comando per il cliente, ma allo stesso volta che abbiamo bisogno di aggiungere codice riportato di seguito alla sezione head di index.html per gestire refresh sul lato client

<!-- 3. Listen on refresh events from the server --> 
<script language="javascript" type="text/javascript"> 
    function init() 
    { 
     websocket = new WebSocket("ws://"+window.location.host+"/websocket"); 
     websocket.onmessage = function(evt) { location.reload(); }; 
    } 
    window.addEventListener("load", init, false); 
</script> 

L'app demo completa che puoi trovare è here

Problemi correlati