Skip to content
Permalink
Browse files

Improvements to support for remote connectivity. Working toward disco…

…nnected and offline client support.
  • Loading branch information...
darkfrog26 committed Aug 19, 2019
1 parent 1f21645 commit 941e3b27ca9c8f016bcf7231742ada40b391454c
@@ -20,6 +20,8 @@ import scala.scalajs.js.|
trait ClientApplication extends YouIApplication with ScreenManager {
ClientApplication.instance = this

def remoteHost: String = window.location.host

addScript("/source-map.min.js")

override def isClient: Boolean = true
@@ -41,7 +41,7 @@ class ClientConnectivity(connectivity: ApplicationConnectivity, application: Cli
} else {
"ws"
}
val url = URL(s"$protocol://${window.location.host}${connectivity.path}")
val url = URL(s"$protocol://${application.remoteHost}${connectivity.path}")
webSocket := Some(WebSocketUtil.connect(url, connection))
}

@@ -0,0 +1,48 @@
package io.youi.app

import java.io.File

import io.youi.http.content.{StringContent, URLContent}
import io.youi.http.{HttpConnection, HttpRequest, HttpStatus}
import io.youi.net.{Path, URL}
import io.youi.stream._

import scala.concurrent.Future
import scribe.Execution.global

class OfflineGenerator(application: ServerApplication,
outputDirectory: File,
baseURL: URL = URL("http://localhost")) {
def generate(paths: List[Path]): Future[Unit] = paths.headOption match {
case Some(path) => {
scribe.info(s"*********** PROCESSING: $path ********************")
application.initialize().flatMap { _ =>
application.handle(HttpConnection(application, HttpRequest(url = baseURL.withPath(path)))).flatMap { connection =>
if (connection.response.status == HttpStatus.OK) {
connection.response.content match {
case Some(content) => {
val file = new File(outputDirectory, path.encoded.substring(1))
file.getParentFile.mkdirs()
scribe.info(s"Writing $path to ${file.getAbsolutePath}..")
content match {
case c: StringContent => IO.stream(c.value, file)
case c: URLContent => IO.stream(c.url, file)
case _ => throw new RuntimeException(s"Unsupported Content-Type: $content")
}
}
case None => scribe.warn(s"No content returned for $path")
}

generate(paths.tail)
} else {
throw new RuntimeException(s"Bad status for: $path - ${connection.response.status}, Content: ${connection.response.content}")
}
}
}
}
case None => {
scribe.info("Finished processing offline generation")
Future.successful(())
}
}
}
@@ -28,14 +28,15 @@ trait YouIApplication extends ErrorSupport with CacheImplementation {

val connectivityEntries: Var[Set[ApplicationConnectivity]] = Var(Set.empty[ApplicationConnectivity])

protected def autoConnectCommunication: Boolean = true

/**
* Default connectivity using "/communication" as the path. Can be overridden if this path is not desirable.
*/
val connectivity: ApplicationConnectivity = createConnectivity()

def createConnectivity(path: String = "/communication",
autoConnect: Boolean = true): ApplicationConnectivity = {
new ApplicationConnectivity(this, path, autoConnect)
def createConnectivity(path: String = "/communication"): ApplicationConnectivity = {
new ApplicationConnectivity(this, path, autoConnectCommunication)
}
}

@@ -7,10 +7,6 @@ import io.youi.{Color, dom}
import io.youi.dom._
import io.youi.example.screen.{CommunicationScreen, ExampleBootstrapScreen, LoginScreen}
import io.youi.example.ui._
//import io.youi.example.ui._
//import io.youi.example.ui.drawable._
//import io.youi.example.ui.hypertext.DataTransferExample
//import io.youi.util.DebugSupport
import org.scalajs.dom._

import scala.scalajs.js.annotation.JSExportTopLevel
@@ -36,10 +36,9 @@ object ServerExampleApplication extends ExampleApplication with ServerApplicatio
combined.any(
path.matches("/examples/.*[.]html"),
path.exact("/ui-examples.html")
) / Application / ProxyCache.delta("/cache") / ServerApplication.AppTemplate,
) / Application / ServerApplication.AppTemplate,
path"/cookies.html" / CookiesExample,
path"/session.html" / SessionExample,
path"/cache" / ProxyCache(),
ClassLoaderPath(pathTransform = (path: String) => s"content$path") / CachingManager.LastModified(),
path.startsWith("/app") / ClassLoaderPath()
)
@@ -54,23 +54,23 @@ trait Server extends HttpHandler with ErrorSupport {
def isInitialized: Boolean = initialized.get()
def isRunning: Boolean = isInitialized && implementation.isRunning

/**
* Init is called on start(), but only the first time. If the server is restarted it is not invoked again.
*/
protected def init(): Future[Unit] = Future.successful(())

def start(): Future[Unit] = {
def initialize(): Future[Unit] = {
val shouldInit = initialized.compareAndSet(false, true)
val future = if (shouldInit) {
if (shouldInit) {
init()
} else {
Future.successful(())
}
}

future.map { _ =>
implementation.start()
scribe.info(s"Server started on ${config.enabledListeners.mkString(", ")}")
}
/**
* Init is called on start(), but only the first time. If the server is restarted it is not invoked again.
*/
protected def init(): Future[Unit] = Future.successful(())

def start(): Future[Unit] = initialize().map { _ =>
implementation.start()
scribe.info(s"Server started on ${config.enabledListeners.mkString(", ")}")
}

def stop(): Unit = synchronized {

0 comments on commit 941e3b2

Please sign in to comment.
You can’t perform that action at this time.