2016-04-20 9 views
2

Ich bewegte mqtt-hs zu LTS-5.13 und kompiliert einfach gut mit stack. Dann habe ich den folgenden Abonnenten erstellt, um eine Themenhierarchie anzuhören. Dies ist der Teilnehmercodebasic mqtt mit haskell

{-# LANGUAGE OverloadedStrings #-} 
module Main(main) where 

import Control.Concurrent (threadWaitRead) 
import System.Posix.Types 
import Network.MQTT 
import Network.MQTT.Logger 

main :: IO() 
main = do 
    conn <- connect defaultConfig { cLogger = warnings stdLogger, cHost = "192.168.0.1" } 
    qos <- subscribe conn Confirm "/something" callback 
    putStrLn "control-c to finish" 
    threadWaitRead $ Fd 1 

callback topic payload = putStrLn $ "A message was published to " ++ show topiC++ ": " ++ show payload 

Wenn ich etwas zu dem Thema (mit einem einfachen Haskell Verlag auch mit), ich das diesem Programm in der Konsole bin immer:

control-c to finish 
[Error] {handle: <socket: 3>}: recvLoop: end of file 
[Error] recvLoop: No reconnect, terminating. 

aber kein anderer Ausgang .

Sowohl Publisher als auch Abonnent sind mit einem Broker (Mosquitto) verbunden. Der Abonnent scheint Ok zu sein, das obige passiert nur, wenn er die Nachricht vom Herausgeber erhält. Die obige Nachricht tritt auch auf, wenn ich den Broker stoppe.

Irgendwelche Ideen?

aktualisieren

ich letzte MQTT-hs kloniert (0.3.0) und führte diese Änderung

--- a/Network/MQTT.hs 
+++ b/Network/MQTT.hs 
@@ -448,9 +448,10 @@ recvLoop :: MQTT -> IO() 
recvLoop m = loopWithReconnect m "recvLoop" $ \mqtt -> do 
    h <- readMVar (handle mqtt) 
    eof <- hIsEOF h 
- if eof 
-  then ioError $ mkIOError eofErrorType "" (Just h) Nothing 
-  else getMessage mqtt >>= dispatchMessage mqtt 
+ getMessage mqtt >>= dispatchMessage mqtt 
+ -- if eof 
+ -- then ioError $ mkIOError eofErrorType "" (Just h) Nothing 
+ -- else getMessage mqtt >>= dispatchMessage mqtt 
    `catch` 
    \e -> logWarning mqtt $ "recvLoop: Caught " ++ show (e :: MQTTException) 

das heißt, ich habe die EOF Prüfung deaktiviert. Jetzt wird die Nachricht an die Konsole gedruckt, aber der Teilnehmer geht so schnell wie möglich in eine Schleife, die [Warning] recvLoop: Caught EOF wirft.

Ist das ein Mücke Fehler oder Fehler in MQT-HS? ohne den Hack

aktualisieren 2

kann ich bestätigen, es mit ActiveMQ funktioniert. Nachdem dies gesagt wurde, ist es besser, wenn mqtt-hs von einer schließenden Verbindung des Brokers zu einem Teilnehmer wiederhergestellt werden könnte.

Antwort

1

Ich glaube, dass Sie es möglicherweise falsch konfiguriert haben. Ich benutze derzeit mqtt-hs in der Produktion und habe fast keine Probleme damit (abgesehen von einem Fehler, der bereits im Github des Projekts behoben wurde). Das neue Update verwendet eine TChan, um die Nachrichten korrekt zuzustellen, da bei einer dauerhaften Verbindung die Möglichkeit besteht, dass einige Nachrichten verloren gehen, da der Handler noch nicht zur Verfügung gestellt wurde.

Sie definieren die Verbindung zum Broker, aber Sie teilen dem Client nicht mit, wie die Reconnections behandelt werden sollen. Als Referenz verwende ich so etwas wie die folgenden im Moment:

mqttConfig :: HostName -> MQTTConfig 
mqttConfig host = defaultConfig { cClean = False 
           , cClientID = "myClientId" 
           , cHost = host 
           , cUsername = Just "username" 
           , cPassword = Just "password" 
           , cKeepAlive = Just 10 
           , cReconnPeriod = Just 1 
           , cLogger = stdLogger } 

Auch wenn die verwendeten Version hier leicht aktualisiert wird, nur sehr wenig benötigt ändern und reconnctions passieren nach Bedarf, wenn der Makler (mosquitto sowie hier) geht nach unten und dann später erholt sich.

+0

Ja, das Hinzufügen von 'cReconnPeriod = Nur 1' behebt es! Ich muss über 'TChan' lesen, aber der einfache Ansatz oben funktioniert mit Fix gegeben. Tnx. – carlosayam