Friday, February 18, 2011

Chicken Scheme's zmq egg


Well, I looked further into zeromq after watching the youtube video and reading the guide.
My last post was just my curiosity about it. Zeromq is a messaging library with many different language bindings although I prefer to use scheme for most programming tasks. Moritz Heidkamp implemented an excellent chicken scheme language binding for zeromq. Zeromq eases the task of writing distributed applications so it can make our life easier and there is no need to learn erlang to accomplish writing distributed programs.

Compared to other language bindings for this library the chicken scheme zmq egg provides a much higher level of abstraction than most of the other language bindings for zeromq messaging library. In my opinion it's a much easier to use binding for working with zeromq.

So I thought I'll try my hand at writing the example programs in scheme from the guide using the zmq egg.
hwserver.scm
(use zmq format loop ports)

(define serializer (make-parameter write))
(define deserializer (make-parameter read))


(define (main)
  (let ((responder (make-socket 'rep))
        (reply "World"))
    (bind-socket responder "tcp://127.0.0.1:5555")
    (loop
     (format #t "Received request: ~A~%"
             (with-input-from-string
                 (let goto ()
                   (let ((msg (receive-message responder)))
                     (or msg (begin
                               (thread-wait-for-i/o! (socket-fd responder) #:input)
                               (goto)))))
               (deserializer)))
    ;; Do some work
     (sleep 1)

     ;; Send reply back to client
     (send-message responder
                   (with-output-to-string (cut (serializer) reply))))))
(main)

hwclient.scm
(use zmq format ports miscmacros)

(define serializer (make-parameter write))
(define deserializer (make-parameter read))

(define (main)
  (let ((sock (make-socket 'req)))
    (format "Connecting to hello world server...~%")
    (connect-socket sock "tcp://127.0.0.1:5555")

    ;; Do 10 requests, waiting each time for a response
    (dotimes (request-cnt 10)
             (let ((request "Hello"))
               (format #t "Sending request ~D...~%" request-cnt)
               (send-message sock
                             (with-output-to-string (cut (serializer) request)))

               ;; Get the reply
              (format #t "Received reply ~D: ~A~%"
                        request-cnt
                        (with-input-from-string
                            (let loop ()
                              (let ((msg (receive-message sock)))
                                (or msg (begin
                                          (thread-wait-for-io! (socket-fd sock) #:input)
                                          (loop)))))
                          (deserializer)))))))
(main)

Networking just got a little more simpler with zeromq. Thanks to Pieter Hintjens, Moritz Heidkamp an every one on #chicken and #zeromq at irc.freenode.net.

No comments: