package spimedb.server; import com.google.common.collect.Sets; import com.google.common.util.concurrent.RateLimiter; import io.undertow.websockets.core.BufferedTextMessage; import io.undertow.websockets.core.StreamSourceFrameChannel; import io.undertow.websockets.core.WebSocketChannel; import io.undertow.websockets.spi.WebSocketHttpExchange; import spimedb.SpimeDB; import javax.script.SimpleBindings; import java.io.IOException; import java.util.Set; /** * Created by me on 3/4/17. */ public class Session extends AbstractServerWebSocket { /** * response bandwidth throttle */ final RateLimiter defaultOutRate; final SpimeDB db; final SimpleBindings scope; protected Set<WebSocketChannel> chan = Sets.newConcurrentHashSet(); public Session(SpimeDB db) { this(db, Double.POSITIVE_INFINITY); } public Session(SpimeDB db, double outputRateLimitBytesPerSecond) { this.defaultOutRate = RateLimiter.create(outputRateLimitBytesPerSecond); this.db = db; scope = new SimpleBindings(); } public void set(String key, Object value) { scope.put(key, value); } @Override public void onConnect(WebSocketHttpExchange exchange, WebSocketChannel socket) { super.onConnect(exchange, socket); if (this.chan.add(socket)) { onConnected(socket); } } protected void onConnected(WebSocketChannel socket) { } @Override protected void onClose(WebSocketChannel socket, StreamSourceFrameChannel channel) throws IOException { super.onClose(socket, channel); if (this.chan.remove(socket)) onDisconnected(socket); } protected void onDisconnected(WebSocketChannel socket) { } /** * interpret text as js code to execute */ @Override protected void onFullTextMessage(WebSocketChannel socket, BufferedTextMessage message) { String code = message.getData().trim(); if (code.isEmpty()) return; //ignore db.runLater(1f, () -> { JSExec.eval(code, scope, db.js, result -> { if (result == null) return; Object resultObj = result.o; if (resultObj instanceof Task) { //if the result of the evaluation is a Task, queue it start((Task) resultObj); } else { //else send the immediate result sendJSONBinary(socket, result.toJSON(), defaultOutRate, null); } }); }); } protected void start(Task t) { db.runLater(1f, () -> { t.run(); t.stop(); }); } }