vert-x / mod-lang-clojure

Vert.x 2.x is deprecated - use instead
http://vertx.io
Other
74 stars 15 forks source link

eventbus_pointtopoint example not working. #116

Closed philoskim closed 10 years ago

philoskim commented 10 years ago

My test environment is as follows.

vertx version: 2.1RC3 (built 2014-04-02 10:07:26) 
io.vertx~lang-clojure~1.0.2

My guess is that eb/on-message may have some problem.

Firstly I ran pointtopoint/receiver.clj as follows.

$ vertx run eventbus_pointtopoint/receiver.clj --cluster 
Started clojure verticle: eventbus_pointtopoint/receiver.clj 
Succeeded in deploying verticle 

And then I ran pointtopoint/sender.clj as follows.

$ vertx run eventbus_pointtopoint/sender.clj --cluster
Started clojure verticle: eventbus_pointtopoint/sender.clj 
Succeeded in deploying verticle 
sent message some-message-1
sent message some-message-2
sent message some-message-3
sent message some-message-4
sent message some-message-5
sent message some-message-6
sent message some-message-7
sent message some-message-8
sent message some-message-9
..........................................

However, the receiver screen didn't show any message at all.

$ vertx run eventbus_pointtopoint/receiver.clj --cluster 
Started clojure verticle: eventbus_pointtopoint/receiver.clj 
Succeeded in deploying verticle 
tobias commented 10 years ago

The switch to enable clustering is -cluster, not --cluster. Try that and let me know if it works for you. It works for me locally when I use -cluster.

philoskim commented 10 years ago

You are right. I made a mistake. The above code is working correctly. Thanks a lot for your reply.

I have a difficulty in running an worker verticle. Could you tell me where I am wrong? I want to run an worker vehicle in embedded vert.x programmatically as follows.

 (ns vertx-embed.main-verticle
  (:require [vertx.core :as vertx]
            [vertx.http :as http]
            [vertx.http.websocket :as ws]
            [vertx.stream :as stream]
            [vertx.embed :as embed]
            [vertx.eventbus :as eb])
  (:import java.util.concurrent.CountDownLatch)
  (:gen-class))

(def address "example.address")

(defn send-msg
  [msg]
  (eb/send address msg
           (fn [reply]
             (println "received message from worker verticle:" reply))))

(defn- start
  []
  (-> (http/server)
      (http/on-request
       (fn [req]
         (when (= "/" (.path req))
           (http/send-file (http/server-response req)
                           "resources/public/ws.html"))))

      (ws/on-websocket
        (fn [ws] (if (= "/myapp" (.path ws))
                   (do 
                     (println "socket connected.")
                     (stream/on-data ws (fn [data]
                                          (println "msg from client:" (str data))
                                          (send-msg (str data)) )))
                   (.reject ws) )))

      (http/listen 8080 "localhost"))

      (println (format "Http server on localhost:8080")))

(defn -main
  [& args]
  (println "main-verticle running.\n")

  (embed/set-vertx! (embed/vertx))
  (let [latch (CountDownLatch. 1)]
    (vertx/deploy-worker-verticle "vertx_embed.worker_verticle.clj" :multi-threaded? true)
    (start)
    (.await latch)))
(ns vertx_embed.worker-verticle
  (:require [vertx.eventbus :as eb]))

(def address "example.address")

(eb/on-message
  address
  (fn [msg]
    (Thread/sleep 1000)   ;; time-consuming task
    (eb/reply msg (str "pong:" msg))))

(println "worker verticle run.")
<!DOCTYPE html>
<html>
  <head><title>Web Socket Test</title></head>
  <body>
    <script>
      var socket;

      if (window.WebSocket) {
        socket = new WebSocket("ws://localhost:8080/myapp");
        socket.onmessage = function(event) {
          alert("Received data from websocket: " + event.data);
        }
        socket.onopen = function(event) {
          alert("Web Socket opened!");
        };
        socket.onclose = function(event) {
          alert("Web Socket closed.");
        };
      } else {
        alert("Your browser does not support Websockets. (Use Chrome)");
      }

      function send(message) {
        if (!window.WebSocket) {
          return;
        }
      if (socket.readyState == WebSocket.OPEN) {
          for (var i = 0; i < 10; i++) { 
            socket.send("hello " + message + " " + i);
          }
        } else {
          alert("The socket is not open.");
        }
      }
    </script>
    <form onsubmit="return false;">
      <input type="text" name="message" value="Hello, World!"/>
      <input type="button" value="Send Web Socket Data" onclick="send(this.form.message.value)"/>
    </form>
  </body>
</html>

I have the following exception message.

$ lein run
main-verticle running.

log4j:WARN No appenders could be found for logger (io.netty.util.internal.logging.InternalLoggerFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "main" org.vertx.java.core.VertxException: No container instance available.
    at vertx.core$get_container.invoke(core.clj:66)
    at vertx.core$get_container.invoke(core.clj:63)
    at vertx.core$deploy_worker_verticle.doInvoke(core.clj:221)
    at clojure.lang.RestFn.invoke(RestFn.java:439)
    at vertx_embed.main_verticle$_main.doInvoke(main_verticle.clj:46)
    at clojure.lang.RestFn.invoke(RestFn.java:397)
    at clojure.lang.Var.invoke(Var.java:411)
    at user$eval5$fn__7.invoke(form-init6359882160858573602.clj:1)
    at user$eval5.invoke(form-init6359882160858573602.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6619)
    at clojure.lang.Compiler.eval(Compiler.java:6609)
    at clojure.lang.Compiler.load(Compiler.java:7064)
    at clojure.lang.Compiler.loadFile(Compiler.java:7020)
    at clojure.main$load_script.invoke(main.clj:294)
    at clojure.main$init_opt.invoke(main.clj:299)
    at clojure.main$initialize.invoke(main.clj:327)
    at clojure.main$null_opt.invoke(main.clj:362)
    at clojure.main$main.doInvoke(main.clj:440)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:419)
    at clojure.lang.AFn.applyToHelper(AFn.java:163)
    at clojure.lang.Var.applyTo(Var.java:532)
    at clojure.main.main(main.java:37)

When I comment out one line as follows and click the button,

......
 (let [latch (CountDownLatch. 1)]
    ;; ( vertx/deploy-worker-verticle "vertx_embed.worker_verticle.clj" :multi-threaded? true)
    (start)
    (.await latch)))
..........

the result is printed on the terminal as I expected.

$ lein run
main-verticle running.

log4j:WARN No appenders could be found for logger (io.netty.util.internal.logging.InternalLoggerFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Http server on localhost:8080
socket connected.
msg from client: hello Hello, World! 0
msg from client: hello Hello, World! 1
msg from client: hello Hello, World! 2
msg from client: hello Hello, World! 3
msg from client: hello Hello, World! 4
msg from client: hello Hello, World! 5
msg from client: hello Hello, World! 6
msg from client: hello Hello, World! 7
msg from client: hello Hello, World! 8
msg from client: hello Hello, World! 9

Where am I wrong?

tobias commented 10 years ago

When using Vert.x embedded, calling vertx.embed/set-vertx! only gives you access to the core Vert.x features, and none of the platform features in vertx.core (basically all of the deploy- functions) will work. To deploy, you have to use the platform functions in vertx.embed.platform. Though if you need access to the platform, I'd recommend trying to use Vert.x non-embedded. You can use https://github.com/isaiah/lein-vertx to have something closer to a standard clojure workflow, but not have to embed.