[cl-irc-devel] Re: server-2 stream issue

Erik Huelsmann ehuels at gmail.com
Wed May 9 13:46:14 UTC 2007


Hi Mikhail,

I'm CC-ing the development list because I've seen this question before
and that way it will be available in the archives for posterity. I
hope you don't mind.

See my comments inline below. In summary, there are 2 problems in your code.

On 5/9/07, Mikhail Shevchuk <mikhail.shevchuk at gmail.com> wrote:
> Hi, Eric
> There are two following threads in my application:
>
>  IRC-UTR-BOT> (make-thread #'irc-read-loop)
> #<THREAD {B30F869}>
> IRC-UTR-BOT> (server-2)
> #<THREAD {B3801F1}>
>
> Here is the source of the package:
>
> (defpackage :irc-utr-bot
>  (:use "CL" "SB-THREAD" "SB-EXT"))
>
> (in-package :irc-utr-bot)
>
> (defvar *irc-channel* (string "#utr"))
>
> ;; connect to IRC-server
> (defvar *irc-connection* (cl-irc:connect :nickname "xmpp-"
>                                         :server "irc.tomsk.ru"
>                                         :port 6667))

You need to do 2 additional things to make the connection work:

1) You need to add the default hooks for the cl-irc library to work correctly
2) You need to call read-message-loop on the connection to handle the
incoming IRC messages.

The above means that this code is missing:

(cl-irc:add-default-hooks *irc-connection*)

> (defvar *jabber-bot-conn* (usocket:socket-stream
> (usocket:socket-connect "213.183.100.107" 9999)))
>
> (cl-irc:join *irc-connection* *irc-channel*) ;; joining channel
>
> (defvar *serv*)
>
> (defun server-2 ()
>  (let ((sock (usocket:socket-listen "88.204.87.138" 3690 :backlog 4
> :reuseaddress t)))
>    (setf *serv* sock)
>    (sb-thread:make-thread #'(lambda ()
>                               (let ((csock (usocket:socket-accept sock)))
>                                    (let ((cstream (usocket:socket-stream csock)))
>                                      (when cstream
>                                        (loop for line = (read-line cstream nil)

Here you may want to check whether the socket is actually still
connected before reading from it. See cl-irc:read-message.

>                                             while line do (progn
>                                                             (cl-irc:privmsg *irc-connection* *irc-channel* (format nil
> "~A" line))))
>                                        (close cstream))))))))
>
> (defun msg-hook (message)
>  (progn
>    (format *jabber-bot-conn* "_~A_: /~a/"
>            (cl-irc:source message) (second (cl-irc:arguments message)))
>    (force-output *jabber-bot-conn*)
>    (format t "_~a_: /~a/"
>          (cl-irc:user message) (second (cl-irc:arguments message)))))
>
> (cl-irc:remove-hooks *irc-connection* 'cl-irc-privmsg-message)
> (cl-irc:add-hook *irc-connection* 'cl-irc:irc-privmsg-message #'msg-hook)
>
> (defun irc-read-loop ()
>  (cl-irc:read-message-loop *irc-connection*))
>
> But this doesn't work well because of the following exception, that is
> raised after some time.
> I don't know the reason of this crash, but I hope you have some ideas.

The problem is that the server sends you IRC messages to which you
have to send an answer. The default cl-irc library does that for you
IFF you configure it correctly; by adding the default hooks to allow
it to handle those messages.

By not adding the hooks, you are effectively telling cl-irc *not* to
handle any IRC traffic for you - meaning that you'll have to provide
all protocol behaviours implemented in cl-irc yourself.

HTH,


Erik.



More information about the cl-irc-devel mailing list