Skip to content

Commit

Permalink
Setup socket.io connection between electron and JVM
Browse files Browse the repository at this point in the history
  • Loading branch information
wilkerlucio committed Dec 26, 2019
1 parent 79db69c commit 81d10ac
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 30 deletions.
1 change: 1 addition & 0 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
com.wsscode/pathom {:mvn/version "2.2.28"}
fulcrologic/fulcro {:mvn/version "2.8.4"}
fulcrologic/fulcro-incubator {:mvn/version "0.0.28"}
io.socket/socket.io-client {:mvn/version "1.0.0"}
org.clojure/clojure {:mvn/version "1.10.1"}
org.clojure/clojurescript {:mvn/version "1.10.597"}}}

Expand Down
13 changes: 13 additions & 0 deletions src/core/com/wsscode/pathom/viz/client.cljc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
(ns com.wsscode.pathom.viz.client
(:require [com.fulcrologic.guardrails.core :refer [>def >defn >fdef => | <- ?]]
[com.wsscode.socket-io.client :as sio-client]
[clojure.spec.alpha :as s]))

(>def ::parser fn?)

(def default-config
{::sio-client/server-url "http://localhost:8238"})

(defn connect [connector parser]
{::sio-client/connector (sio-client/connect (merge default-config connector))
::parser parser})
19 changes: 19 additions & 0 deletions src/core/com/wsscode/socket_io/client.cljc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
(ns com.wsscode.socket-io.client
(:require [com.fulcrologic.guardrails.core :refer [>def >defn >fdef => | <- ?]]
[clojure.spec.alpha :as s]))

(>def ::server-url string?)
(>def ::connector (s/keys :req [::send-message]))

(>def ::connect fn?)
(>def ::send-message fn?)

(>def ::on-client-message fn?)

(def default-config
{::server-url "http://localhost"})

(def ^String transfer-key "transit-message")

(defn connect [{::keys [connect] :as connector}]
(connect connector))
54 changes: 54 additions & 0 deletions src/core/com/wsscode/socket_io/client_connectors/io_socket.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
(ns com.wsscode.socket-io.client-connectors.io-socket
(:require [com.wsscode.socket-io.client :as sio-client]
[com.wsscode.transit :as t])
(:import (io.socket.client IO Socket)
(io.socket.emitter Emitter$Listener)
(org.json JSONObject)))

(deftype Listener [callback]
Emitter$Listener
(call [& args]
(apply callback args)))

(defn listener [callback]
(->Listener callback))

(defn event-connect [config]
(println "CONNECT" config))

(defn event-message [{::sio-client/keys [on-client-message] :as connector} ^JSONObject message]
(try
(when-let [transit-msg (.getString message sio-client/transfer-key)]
(println "EVENT" message)
(if on-client-message
(on-client-message connector (t/read transit-msg))))
(catch Throwable e
(println "event missing transit message"))))

(defn connect [{::sio-client/keys [server-url] :as connector}]
(println "CONNECT TO" server-url)
(let [socket (doto (IO/socket ^String server-url)
(.on Socket/EVENT_CONNECT
(listener #(event-connect connector)))

(.on "event"
(listener #(event-message connector %)))

(.connect))]
(assoc connector ::socket socket)))

(defn send-message [{::keys [^Socket socket]} msg]
(.emit socket "event"
(doto (JSONObject.)
(.put sio-client/transfer-key (t/write msg)))))

(defn socket-io-connector
([] (socket-io-connector {}))
([config]
(merge
config
{::sio-client/connect
connect

::sio-client/send-message
send-message})))
64 changes: 64 additions & 0 deletions src/core/com/wsscode/socket_io/server.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
(ns com.wsscode.socket-io.server
(:require
["socket.io" :as Server]
[com.wsscode.transit :as t]
[com.fulcrologic.guardrails.core :refer [>def >defn >fdef => | <- ?]]))

(>def ::port pos-int?)
(>def ::server-connection any?)
(>def ::client-connection any?)
(>def ::client-id string?)

(>def ::on-client-connect fn?)
(>def ::on-client-message fn?)
(>def ::on-client-disconnect fn?)

(defn send-message [emmiter msg]
(.emit emmiter "event" #js {"transit-message" (t/write msg)}))

(defn setup-client-events
[{::keys [clients on-client-message on-client-disconnect] :as config}
{::keys [client-connection client-id]}]
(.on client-connection "event"
(fn [data reply-fn]
(if on-client-message
(on-client-message config
{::client-id client-id
::event-data data
::reply-fn reply-fn}))))

(.on client-connection "disconnect"
(fn [data reply-fn]
(println "DISCONNECT CLIENT")
(if on-client-disconnect
(on-client-disconnect config
{::client-id client-id
::event-data data
::reply-fn reply-fn}))

(swap! clients dissoc client-id)))

nil)

(defn start-socket-io-server
[{::keys [port on-client-connect] :as config}]
(let [io (Server)
clients (atom {})
config' (assoc config
::server-connection io
::clients clients)]
(.on io "connection"
(fn [client-connection]
(let [client-id (gensym "client-id-")
client {::client-connection client-connection
::client-id client-id}]
(swap! clients assoc client-id client)

(if on-client-connect
(on-client-connect config' client))

(setup-client-events config' client))))

(.listen io port)

config'))
25 changes: 25 additions & 0 deletions src/core/com/wsscode/transit.cljc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
(ns com.wsscode.transit
(:refer-clojure :exclude [read write])
(:require [cognitect.transit :as t])
#?(:clj (:import (java.io ByteArrayOutputStream ByteArrayInputStream))))

(defn read [s]
#?(:clj
(let [in (ByteArrayInputStream. (.getBytes s))
reader (t/reader in :json)]
(t/read reader))

:cljs
(let [reader (t/reader :json)]
(t/read reader s))))

(defn ^String write [x]
#?(:clj
(let [out (ByteArrayOutputStream. 4096)
writer (t/writer out :json)]
(t/write writer x)
(.toString out))

:cljs
(let [writer (t/writer :json)]
(t/write writer x))))
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,19 @@
["path" :as path]
["url" :as url]))

(defonce contents (atom nil))

(defn create-window []
(let [win (electron/BrowserWindow. #js {:width 800
:height 600
:webPreferences #js {:nodeIntegration true}})]
(.loadURL win (url/format #js {:pathname (path/join js/__dirname ".." ".." "index.html")
:protocol "file:"
:slashes "true"}))
(.. win -webContents openDevTools)
(reset! contents (.-webContents win))))
(.. win -webContents openDevTools)))

(defn init []
(js/console.log "start")
(electron/app.on "ready" create-window)
(server/start! {:content-atom contents}))
(server/start! {}))

(defn after-load []
(js/console.log "Done reloading"))
41 changes: 16 additions & 25 deletions src/electron/com/wsscode/pathom/viz/electron/background/server.cljs
Original file line number Diff line number Diff line change
@@ -1,32 +1,23 @@
(ns com.wsscode.pathom.viz.electron.background.server
(:require
[cljs.nodejs :as nodejs]
["electron" :refer [ipcMain]]
["socket.io" :as Server]
[goog.object :as gobj]
[fulcro.inspect.remote.transit :as encode]))
[com.wsscode.electron.ipc-main :as ipc-main]
[com.wsscode.socket-io.server :as io-server]))

(goog-define SERVER_PORT 8237)
(defonce the-client (atom nil))
(goog-define SERVER_PORT 8238)

(defn process-client-message [web-contents msg reply-fn]
(try
(when web-contents
(.send web-contents "event" #js {"fulcro-inspect-remote-message" msg}))
(catch :default e
(js/console.error e))))
(defn start! [env]
(io-server/start-socket-io-server
{::io-server/port
SERVER_PORT

(defn start! [{:keys [content-atom]}]
(let [io (Server)]
(.on ipcMain "event" (fn [evt arg]
(when @the-client
(.emit @the-client "event" arg))))
(.on io "connection" (fn [client]
(reset! the-client client)
(.on client "event"
(fn [data reply-fn]
(when-let [web-contents (some-> content-atom deref)]
(process-client-message web-contents data reply-fn))))))
(.listen io SERVER_PORT)))
::io-server/on-client-connect
(fn [env {::io-server/keys [client-connection] :as client}]
(js/console.log "Client connected" client)
(io-server/send-message client-connection "Hello dear"))

::io-server/on-client-message
(fn [_ msg]
(js/console.log "NEW MSG" msg))

::io-server/on-client-disconnect
(fn [_ client])}))
22 changes: 22 additions & 0 deletions test/com/wsscode/pathom/viz/connectors/socket_io_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
(ns com.wsscode.pathom.viz.connectors.socket-io-test
(:require [com.wsscode.socket-io.client-connectors.io-socket :as sio]
[com.wsscode.pathom.viz.client :as pvc]
[com.wsscode.pathom.core :as p]
[com.wsscode.pathom.connect :as pc]))

(def parser
(p/parser
{::p/env {::p/reader [p/map-reader
pc/reader3
pc/open-ident-reader
p/env-placeholder-reader]
::p/placeholder-prefixes #{">"}}
::p/mutate pc/mutate
::p/plugins [(pc/connect-plugin {::pc/parser-id `parser
::pc/register []})
p/error-handler-plugin
p/trace-plugin]}))

(comment
(-> (sio/socket-io-connector {})
(pvc/connect parser)))

0 comments on commit 81d10ac

Please sign in to comment.