owned this note
owned this note
Published
Linked with GitHub
---
tags: ASF
---
# Submarine websocket design doc
[tutorial](https://docs.oracle.com/javaee/7/tutorial/websocket.htm#GKJIQ5)
[Examples](https://github.com/jetty-project/embedded-jetty-websocket-examples/tree/10.0.x/native-jetty-websocket-example/src)
[ws on typescript](https://zhuanlan.zhihu.com/p/68527022)
## workflow


## Setup
```java=
private static void setupWebSocketServer(WebAppContext webapp,
SubmarineConfiguration conf, ServiceLocator serviceLocator) {
String maxTextMessageSize = conf.getWebsocketMaxTextMessageSize();
final ServletHolder notebookServletHolder =
new ServletHolder(serviceLocator.getService(WebSocketServer.class));
notebookServletHolder.setInitParameter("maxTextMessageSize", maxTextMessageSize);
final ServletHolder experimentServletHolder =
new ServletHolder(serviceLocator.getService(WebSocketServer.class));
experimentServletHolder.setInitParameter("maxTextMessageSize", maxTextMessageSize);
final ServletHolder environmentServletHolder =
new ServletHolder(serviceLocator.getService(WebSocketServer.class));
environmentServletHolder.setInitParameter("maxTextMessageSize", maxTextMessageSize);
final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
webapp.addServlet(notebookServletHolder, "/ws/notebook/*");
webapp.addServlet(experimentvletHolder, "/ws/experiment/*");
webapp.addServlet(environmentServletHolder, "/ws/environment/*");
}
```
## Server
#### TODO Send Message
```java=
@ManagedObject
public class WebSocketServer extends WebSocketServlet
implements WebSocketSocketListener {
/**
* Job manager service type.
*/
protected enum JobManagerServiceType {
JOB_MANAGER_PAGE("JOB_MANAGER_PAGE");
private String serviceTypeKey;
JobManagerServiceType(String serviceType) {
this.serviceTypeKey = serviceType;
}
String getKey() {
return this.serviceTypeKey;
}
}
private static final Logger LOG = LoggerFactory.getLogger(WebSocketServer.class);
private static Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.registerTypeAdapter(Date.class, new DateJsonDeserializer())
.setPrettyPrinting()
.create();
private static AtomicReference<WebSocketServer> self = new AtomicReference<>();
private ConnectionManager connectionManager;
private ExecutorService executorService = Executors.newFixedThreadPool(10);
public WebSocketServer() {
this.connectionManager = new ConnectionManager();
WebSocketServer.self.set(this);
LOG.info("WebSocketServer instantiated: {}", this);
}
@Override
public void configure(WebSocketServletFactory factory) {
factory.setCreator(new WebSocketWebSocketCreator(this));
}
@Override
public void onOpen(WebSocketSocket conn) {
LOG.info("New connection from {}", conn);
connectionManager.addConnection(conn);
}
@Override
public void onMessage(WebSocketSocket conn, String msg) {
try {
LOG.info("Got Message: " + msg);
if (StringUtils.isEmpty(conn.getUser())) {
connectionManager.addUserConnection("FakeUser1", conn);
}
} catch (Exception e) {
LOG.error("Can't handle message: " + msg, e);
try {
conn.send(serializeMessage(new Message(Message.OP.ERROR_INFO).put(
"info", e.getMessage())));
} catch (IOException iox) {
LOG.error("Fail to send error info", iox);
}
}
}
@Override
public void onClose(WebSocketSocket conn, int code, String reason) {
LOG.info("Closed connection to {} ({}) {}", conn, code, reason);
connectionManager.removeConnection(conn);
connectionManager.removeUserConnection(conn.getUser(), conn);
}
public ConnectionManager getConnectionManager() {
return connectionManager;
}
protected Message deserializeMessage(String msg) {
return gson.fromJson(msg, Message.class);
}
protected String serializeMessage(Message m) {
return gson.toJson(m);
}
public void broadcast(Message m) {
connectionManager.broadcast(m);
}
@ManagedAttribute
public Set<String> getConnectedUsers() {
return connectionManager.getConnectedUsers();
}
@ManagedOperation
public void sendMessage(String message) {
Message m = new Message(Message.OP.NOTICE);
m.data.put("notice", message);
connectionManager.broadcast(m);
}
}
```
## Websocket and React
Reference: [A simple WebSocket between Java and React ](https://dev.to/fpeluso/a-simple-websocket-between-java-and-react-5c98)
## Problems
* How to get the info from watcher
* watch implemention k8s client newer version
* sidecar structure
* possible solution: build a socket client in watcher
* \# of client
* pros: maybe easier to do
* cons: may loss connection
* Sidecar vs k8s submitter
* why ```package()```??