суббота, 22 сентября 2018 г.

clojure websocket client example

This is my deps.edn
https://github.com/middlesphere/spacemacs-clojure-cheatsheet/blob/master/.clojure/deps.edn

1) Start REPL with necessary deps.

clojure -R:1.10:repl:add-lib:test:debug-tools:rebel:xml-bind -m nrepl.cmdline -p 7888 -i -m "[refactor-nrepl.middleware/wrap-refactor,cider.nrepl/cider-middleware]"
nREPL server started on port 7888 on host 0:0:0:0:0:0:0:0 - nrepl://0:0:0:0:0:0:0:0:7888
nREPL 0.4.5
Clojure 1.10.0-alpha8
Java HotSpot(TM) 64-Bit Server VM 10.0.2+13
user=> (use 'clojure.tools.deps.alpha.repl)
nil
user=> (add-lib 'stylefruits/gniazdo {:mvn/version "1.0.1"})
true
user=> (add-lib 'http-kit {:mvn/version "2.2.0"})
true

2) Create empty file (e.g a.clj), connect to REPL (port 7888)  and put following code there:

;; ------------server code --------------------

(use 'org.httpkit.server)

(defn async-handler [ring-request]
  ;; unified API for WebSocket and HTTP long polling/streaming
  (with-channel ring-request channel    ; get the channel
    (if (websocket? channel)            ; if you want to distinguish them
      (on-receive channel (fn [data]     ; two way communication
                            (send! channel data)))
      (send! channel {:status  200
                      :headers {"Content-Type" "text/plain"}
                      :body    "Long polling?"}))))

(run-server async-handler {:port 8080})

;; ------------client code --------------------

(require '[gniazdo.core :as ws])

(def socket (ws/connect "ws://localhost:8080/" :on-receive #(prn 'received %)))
(ws/send-msg socket "hello")
(ws/send-msg socket "world")

(ws/close socket)

вторник, 11 сентября 2018 г.

Run lein with cider from command line



Headless mode

lein update-in :dependencies conj \[org.clojure/tools.nrepl\ \"0.2.13\"\ \:exclusions\ \[org.clojure/clojure\]\] -- update-in :plugins conj \[refactor-nrepl\ \"2.4.0\"\] -- update-in :plugins conj \[cider/cider-nrepl\ \"0.18.0\"\] -- with-profile +mike-local repl :headless :host ::

Interactive mode

lein update-in :dependencies conj \[org.clojure/tools.nrepl\ \"0.2.13\"\ \:exclusions\ \[org.clojure/clojure\]\] -- update-in :plugins conj \[refactor-nrepl\ \"2.4.0\"\] -- update-in :plugins conj \[cider/cider-nrepl\ \"0.18.0\"\] -- with-profile +mike-local repl :start :host ::


where mike-local is my profile

Also, :port parameter can be used to run REPL on custom port.

воскресенье, 2 сентября 2018 г.

clojure cli repl rebel

First way

In order to run REPL (nREPL) server via clojure cli tools with beautiful rebel capabilities just add following section into deps.edn file:

:aliases {
                :repl {:extra-deps {cider/cider-nrepl                       {:mvn/version "0.18.0"}
                                               nrepl                                        {:mvn/version "0.4.5"}
                                               refactor-nrepl                          {:mvn/version "2.4.0"}
                                               com.bhauman/rebel-readline  {:mvn/version "0.1.4"}}
                  :main-opts  ["-e" "(require,(quote,cider-nrepl.main)),"
                               "-e" "(cider-nrepl.main/init,[\"refactor-nrepl.middleware/wrap-refactor\",\"cider.nrepl/cider-middleware\"])"
                               "-e" "(use,'rebel-readline.main),(rebel-readline.main/-main)"]}

}

Then just run with command: clojure -A:repl

Second way

:aliases {
 :repl {:extra-deps {cider/cider-nrepl          {:mvn/version "0.18.0"}
                               nrepl                      {:mvn/version "0.4.5"}
                               refactor-nrepl             {:mvn/version "2.4.0"}
                               com.bhauman/rebel-readline {:mvn/version "0.1.4"}}
                  }
}

clj -R:repl -m nrepl.cmdline -p 7888 -i -m "[refactor-nrepl.middleware/wrap-refactor,cider.nrepl/cider-middleware]"

This command runs repl without rebel capabilities. In order to enable rebel just call it:

user=> (use 'rebel-readline.main)
nil
user=> (rebel-readline.main/-main)
[Rebel readline] Type :repl/help for online help info
user=>


Also, read the docs https://nrepl.readthedocs.io/en/latest/usage/

воскресенье, 20 мая 2018 г.

socks proxy on centos 7

0. yum install gcc pam-devel tcp_wrappers-devel

1. yum install http://mirror.ghettoforge.org/distributions/gf/gf-release-latest.gf.el7.noarch.rpm

2. yum --enablerepo=gf-plus install dante-server

3. systemctl enable sockd.service

4. mkdir /var/run/sockd

5. cp /etc/sockd.conf /etc/sockd.conf.orig

6. vi /etc/sockd.conf


# the server will log both via syslog, to stdout and to /var/log/sockd.log                                                                                                                                
logoutput: syslog stdout /var/log/sockd.log
logoutput: stderr

# The server will bind to the address 10.1.1.1, port 1080 and will only                                                                                                                                   
# accept connections going to that address.                                                                                                                                                               
#internal: 10.1.1.1 port = 1080                                                                                                                                                                           
# Alternatively, the interface name can be used instead of the address.                                                                                                                                   
internal: eth0 port = 80

# all outgoing connections from the server will use the IP address                                                                                                                                        
# 195.168.1.1                                                                                                                                                                                             
#external: 192.168.1.1                                                                                                                                                                                    
external: eth0

# list over acceptable authentication methods, order of preference.                                                                                                                                       
# An authentication method not set here will never be selected.                                                                                                                                           
#                                                                                                                                                                                                         
# If the socksmethod field is not set in a rule, the global                                                                                                                                               
# socksmethod is filled in for that rule.                                                                                                                                                                 
#                                                                                                                                                                                                         

# methods for socks-rules.                                                                                                                                                                                
socksmethod: username

#                                                                                                                                                                                                         
# User identities, an important section.                                                                                                                                                                  
#                                                                                                                                                                                                         

# when doing something that can require privilege, it will use the                                                                                                                                        
# userid "sockd".                                                                                                                                                                                         
user.privileged: root

# when running as usual, it will use the unprivileged userid of "sockd".                                                                                                                                  

user.unprivileged: nobody

client pass {
        from: 0.0.0.0/0 to: 0.0.0.0/0
        log: error connect disconnect
}

client block {
        from: 0.0.0.0/0 to: 0.0.0.0/0
        log: connect error
}

socks pass {
        from: 0.0.0.0/0 to: 0.0.0.0/0
        log: error connect disconnect
}

socks block {
        from: 0.0.0.0/0 to: 0.0.0.0/0
        log: connect error

}


7. sudo useradd -s /bin/false proxyuser

8. sudo passwd proxyuser

9. systemctl start sockd.service


четверг, 15 февраля 2018 г.

core.async tip from Tim Baldridge

If I'm understand the problem I think this is by design. Closing a channel results in a logical termination value being put into the channel.

This is so that, by default, core.async won't loose data.

Most of the time when I encounter this problem I fix it by draining the channel:

(defn drain [c]
  (go (while (not (nil? (<! c)))
          nil)))


And then:

(close! c)
(drain c)

среда, 14 февраля 2018 г.

clojure ring async example

;;requirements

[ring "1.6.3"]
[ring/ring-jetty-adapter "1.6.3"]
[org.clojure/core.async "0.4.474"]
[org.immutant/web "2.1.10"]

;;Jetty

(ns test01.core
  (:gen-class)
  (:require [ring.adapter.jetty :as jetty]
            [clojure.core.async :refer [go chan <! <!! >! >!! timeout close!]]))


(defn what-is-my-ip [request respond raise]
  (respond {:status  200
            :headers {"Content-Type" "text/plain"}
            :body    (:remote-addr request)}))



(defn what-is-my-ip2 [request respond raise]
  (let [ch (chan)]
    (go
      (respond (<! ch)))
    (go
      ;;(<! (timeout 2000))
      (>! ch {:status  200
              :headers {"Content-Type" "text/plain"}
              :body    (:remote-addr request)}))))

(defn start-server
  [handler]
  (jetty/run-jetty handler {:host "localhost" :async? true :port 8080 :path "/" :join? false}))


(defn -main
  "entry point"
  [& args]
  (println "Hello, world."))

;; (def s (start-server what-is-my-ip))
;; (.stop s)
;;(def s (start-server what-is-my-ip2))

;;Immutant

(ns test01.imm
  (:require [immutant.web :as web]
            [immutant.web.async :as async]))


(defn app [request]
  (async/as-channel request
                    {:on-open (fn [stream]
                                (async/send! stream {:status  200
                                                     :headers {"Content-Type" "text/plain"}
                                                     :body    (:remote-addr request)}
                                             {:close? true}))}))


(defn start-server [h]
  (web/run h {:host "localhost" :port 8080}))

(def s (start-server app))

(web/stop s)




среда, 27 декабря 2017 г.

clojure cli and nrepl

Today, I will show you how to run nrepl server and connect emacs to it.

1. Create empty folder helloproject

2. Create file deps.edn in helloproject folder and put here the following content:
{:deps {clj-time {:mvn/version "0.14.2"}}
 :aliases {:repl {:extra-deps
                  {cider/cider-nrepl       {:mvn/version "0.16.0-SNAPSHOT"}
                   org.clojure/tools.nrepl {:mvn/version "0.2.12"}
                   refactor-nrepl          {:mvn/version "2.3.1"}}}}}

Here we import library clj-time from Maven repo, and  import extra deps under alias :repl

3. Now create src folder in helloproject folder,.i.e helloproject/src

4. Create file hello.clj in helloproject/src folder and put here the following content:
(ns hello
  (:require [clj-time.core :as t]
            [clj-time.format :as f]))

(defn time-str
  "Returns a string representation of a datetime in the local time zone."
  [dt]
  (f/unparse
   (f/with-zone (f/formatter "hh:mm aa") (t/default-time-zone))
   dt))

(defn -main []
  (println "Hello world, the time is" (time-str (t/now))))

5. Now we are ready to run repl. Change dir to helloproject and run command: clj -R:repl
The clj parameter -R:repl is important to load extra deps. If you have several aliases then you should list them comma separated, i.e. clj -R:alias1,alias2

After run command clj -R:repl you should see the prompt:
Clojure 1.9.0
user=> 

6. Now we may start nrepl server. Enter the following  two commands in repl:

(require '[clojure.tools.nrepl.server :refer [start-server]] '[cider.nrepl :refer [cider-nrepl-handler]])

(let [port (or (some-> (first *command-line-args*) (java.lang.Long/parseLong)) 7888)] (start-server :port port :handler cider-nrepl-handler) (println "Started nREPL on port" port))


7. After successful nrepl server start you may open helloproject/src/hello.clj in your favourite editor and connect to remote repl.

In Emacs: M-x cider-connect
then enter: localhost and 7888