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@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.
2007/5/9, Erik Huelsmann ehuels@gmail.com:
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.
Sure, but I thought that doesn't refer to the cl-irc because this exception was raised in another thread. But your comments are always useful, thanks.
You need to do 2 additional things to make the connection work:
- You need to add the default hooks for the cl-irc library to work correctly
Oh, didn't know that. Do those default hooks add the ping/pong thing too?
- You need to call read-message-loop on the connection to handle the
incoming IRC messages.
The last one exists at the end of source file already in the separate function. I start it in its own thread.
(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.
What's the relation between cl-irc:read-message and that socket? What is the best way to check the "usocket" connection ?
And one more question about cl-irc: how can I handle "action" messages on the channel?