mirror of
https://github.com/enso-org/enso.git
synced 2024-11-25 10:43:02 +03:00
DRAFT: working language server connection
This commit is contained in:
parent
071a524723
commit
b51843c198
@ -10,6 +10,6 @@ declare global {
|
||||
|
||||
const wss = new WebSocketServer({ host: 'localhost', port: 1234 })
|
||||
|
||||
wss.onconnect = (socket, url) => setupGatewayClient(socket, "ws://localhost:8080", url)
|
||||
wss.onconnect = (socket, url) => setupGatewayClient(socket, "ws://127.0.0.1:30616", 'index')
|
||||
|
||||
wss.start()
|
||||
|
@ -165,9 +165,12 @@ class YjsConnection extends ObservableV2<{ close(): void }> {
|
||||
}
|
||||
|
||||
send(message: Uint8Array) {
|
||||
if (this.ws.readyState !== WebSocket.CONNECTING && this.ws.readyState !== WebSocket.OPEN) {
|
||||
if (this.ws.readyState !== 0 && this.ws.readyState !== 1) {
|
||||
this.close()
|
||||
}
|
||||
/* if (this.ws.readyState !== WebSocket.CONNECTING && this.ws.readyState !== WebSocket.OPEN) {
|
||||
this.close()
|
||||
} */
|
||||
try {
|
||||
this.ws.send(message, (error) => error && this.close())
|
||||
} catch (e) {
|
||||
|
@ -156,14 +156,14 @@ class JsonConnectionController(
|
||||
.subscribe(self, classOf[RefactoringProtocol.ProjectRenamedNotification])
|
||||
}
|
||||
|
||||
override def receive: Receive = {
|
||||
override def receive: Receive = LoggingReceive {
|
||||
case JsonRpcServer.WebConnect(webActor, _) =>
|
||||
unstashAll()
|
||||
context.become(connected(webActor))
|
||||
case _ => stash()
|
||||
}
|
||||
|
||||
private def connected(webActor: ActorRef): Receive = {
|
||||
private def connected(webActor: ActorRef): Receive = LoggingReceive {
|
||||
case req @ Request(Ping, _, Unused) =>
|
||||
val handler = context.actorOf(
|
||||
PingHandler.props(
|
||||
@ -212,7 +212,7 @@ class JsonConnectionController(
|
||||
clientId: UUID,
|
||||
request: Request[_, _],
|
||||
receiver: ActorRef
|
||||
): Receive = {
|
||||
): Receive = LoggingReceive {
|
||||
case _: InitializationComponentInitialized =>
|
||||
logger.info("RPC session initialized for client [{}].", clientId)
|
||||
val session = JsonSession(clientId, self)
|
||||
@ -268,7 +268,7 @@ class JsonConnectionController(
|
||||
receiver: ActorRef,
|
||||
cancellable: Cancellable,
|
||||
rootsSoFar: List[ContentRootWithFile]
|
||||
): Receive = {
|
||||
): Receive = LoggingReceive {
|
||||
case ContentRootManagerProtocol.ContentRootsAddedNotification(roots) =>
|
||||
val allRoots = roots ++ rootsSoFar
|
||||
val hasProject = roots.exists {
|
||||
|
@ -9,6 +9,7 @@ import org.enso.polyfill.encoding.EncodingPolyfill;
|
||||
import org.enso.polyfill.timers.TimersPolyfill;
|
||||
import org.enso.polyfill.web.AbortControllerPolyfill;
|
||||
import org.enso.polyfill.web.EventTargetPolyfill;
|
||||
import org.enso.polyfill.web.PerformancePolyfill;
|
||||
import org.enso.polyfill.websocket.WebSocketPolyfill;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.HostAccess;
|
||||
@ -36,7 +37,7 @@ public class Main {
|
||||
.allowExperimentalOptions(true)
|
||||
.option("js.commonjs-require", "true")
|
||||
.option("js.commonjs-require-cwd", commonJsRoot);
|
||||
var chromePort = 34567;// Integer.getInteger("inspectPort", -1);
|
||||
var chromePort = 34567; //Integer.getInteger("inspectPort", -1);
|
||||
if (chromePort > 0) {
|
||||
b.option("inspect", ":" + chromePort);
|
||||
}
|
||||
@ -49,6 +50,9 @@ public class Main {
|
||||
CompletableFuture
|
||||
.supplyAsync(b::build, executor)
|
||||
.thenAcceptAsync(ctx -> {
|
||||
var performance = new PerformancePolyfill();
|
||||
performance.initialize(ctx);
|
||||
|
||||
var eventTarget = new EventTargetPolyfill(executor);
|
||||
eventTarget.initialize(ctx);
|
||||
|
||||
|
@ -0,0 +1,41 @@
|
||||
package org.enso.polyfill.web;
|
||||
|
||||
import java.util.Arrays;
|
||||
import org.enso.polyfill.Polyfill;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.Source;
|
||||
import org.graalvm.polyglot.Value;
|
||||
import org.graalvm.polyglot.proxy.ProxyExecutable;
|
||||
|
||||
public final class PerformancePolyfill implements ProxyExecutable, Polyfill {
|
||||
|
||||
private static final String NOW = "now";
|
||||
|
||||
private static final String PERFORMANCE_POLYFILL_JS = "performance-polyfill.js";
|
||||
|
||||
public PerformancePolyfill() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(Context ctx) {
|
||||
Source performancePolyfillJs = Source
|
||||
.newBuilder("js", PerformancePolyfill.class.getResource(PERFORMANCE_POLYFILL_JS))
|
||||
.buildLiteral();
|
||||
|
||||
ctx.eval(performancePolyfillJs).execute(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execute(Value... arguments) {
|
||||
var command = arguments[0].asString();
|
||||
System.err.println(command + " " + Arrays.toString(arguments));
|
||||
|
||||
return switch (command) {
|
||||
case NOW ->
|
||||
System.currentTimeMillis();
|
||||
|
||||
default ->
|
||||
throw new IllegalStateException(command);
|
||||
};
|
||||
}
|
||||
}
|
@ -128,7 +128,6 @@ public final class WebSocketPolyfill implements ProxyExecutable, Polyfill {
|
||||
}
|
||||
|
||||
var wsClient = WsClient.builder()
|
||||
.addHeader("Connection", "Upgrade")
|
||||
.protocolConfig(protocolConfig.build())
|
||||
.build();
|
||||
wsClient.connect(uri, connection);
|
||||
@ -284,6 +283,7 @@ public final class WebSocketPolyfill implements ProxyExecutable, Polyfill {
|
||||
listener.executeVoid(event);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error dispatching event [" + type + "] " + listener + " " + event + " " + e);
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
(function (jvm) {
|
||||
|
||||
class Performance {
|
||||
|
||||
now() {
|
||||
return jvm('now');
|
||||
};
|
||||
}
|
||||
|
||||
globalThis.performance = new Performance();
|
||||
|
||||
})
|
@ -0,0 +1,57 @@
|
||||
package org.enso.polyfill;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import org.enso.polyfill.web.PerformancePolyfill;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class PerformanceTest {
|
||||
|
||||
private Context context;
|
||||
private ExecutorService executor;
|
||||
|
||||
public PerformanceTest() {
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
executor = Executors.newSingleThreadExecutor();
|
||||
var eventTarget = new PerformancePolyfill();
|
||||
var b = Context.newBuilder("js");
|
||||
|
||||
var chromePort = Integer.getInteger("inspectPort", -1);
|
||||
if (chromePort > 0) {
|
||||
b.option("inspect", ":" + chromePort);
|
||||
}
|
||||
|
||||
context = CompletableFuture
|
||||
.supplyAsync(() -> {
|
||||
var ctx = b.build();
|
||||
eventTarget.initialize(ctx);
|
||||
return ctx;
|
||||
}, executor)
|
||||
.get();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
executor.close();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void now() throws Exception {
|
||||
var result = CompletableFuture
|
||||
.supplyAsync(() -> context.eval("js", "performance.now()"), executor)
|
||||
.get();
|
||||
|
||||
Assert.assertTrue(result.asLong() > 0);
|
||||
Assert.assertTrue(result.asLong() <= System.currentTimeMillis());
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,7 @@ package org.enso.jsonrpc
|
||||
|
||||
import akka.NotUsed
|
||||
import akka.actor.{ActorRef, ActorSystem, Props}
|
||||
import akka.http.scaladsl.model.headers
|
||||
import akka.http.scaladsl.model.ws.{BinaryMessage, Message, TextMessage}
|
||||
import akka.http.scaladsl.server.Directives._
|
||||
import akka.http.scaladsl.server.Route
|
||||
@ -10,6 +11,7 @@ import akka.stream.{Materializer, OverflowStrategy}
|
||||
import com.typesafe.scalalogging.LazyLogging
|
||||
|
||||
import java.util.UUID
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.ExecutionContext
|
||||
|
||||
@ -94,7 +96,7 @@ class JsonRpcServer(
|
||||
override protected def serverRoute(port: Int): Route = {
|
||||
val webSocketEndpoint =
|
||||
path(config.path) {
|
||||
get { handleWebSocketMessages(newUser(port)) }
|
||||
get { handleWebSocketMessages1(newUser(port)) }
|
||||
}
|
||||
|
||||
optionalEndpoints.foldLeft(webSocketEndpoint) { (chain, next) =>
|
||||
@ -104,6 +106,21 @@ class JsonRpcServer(
|
||||
|
||||
override protected def secureConfig(): Option[SecureConnectionConfig] =
|
||||
config.secureConfig
|
||||
|
||||
// TODO[DB]: Workaround for helidon-io/helidon#8647
|
||||
private def handleWebSocketMessages1(
|
||||
handler: Flow[Message, Message, Any]
|
||||
): Route =
|
||||
extractWebSocketUpgrade { upgrade =>
|
||||
complete(
|
||||
upgrade
|
||||
.handleMessages(handler, None)
|
||||
.mapHeaders(_.map { h =>
|
||||
if (h.is("connection")) headers.Connection("Upgrade") else h
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object JsonRpcServer {
|
||||
|
Loading…
Reference in New Issue
Block a user