示例#1
0
def publishAtQos2(sock, topic, message, retain):
    """
        Description:
            发送一则服务质量等级为2的消息。
        Args:
            sock(Socket):
                客户端socket对象。
            topic(string):
                消息主题。
            message(string):
                消息内容。
            retain(int):
                消息保留标志。
        Returns:
            packetIdentifier(int)
                本次请求使用的报文标识符。
        Raises:
            IOException
                socket连接异常。
    """
    packetIdentifier = generatePacketIdentifier()
    sendMessage(
        sock,
        encoders.PUBLISH_Encoder(0, 2, retain, topic, packetIdentifier,
                                 message))
    tmpPublishAtQos2.append({
        "packetIdentifier": packetIdentifier,
        "waitingFor": 'PUBREC'
    })
    return packetIdentifier
示例#2
0
def publishAtQos0(sock, topic, message, retain):
    """
        Description:
            发送一则服务质量等级为0的消息。
        Args:
            sock(Socket):
                客户端socket对象。
            topic(string):
                消息主题。
            message(string):
                消息内容。
            retain(int):
                消息保留标志。
        Returns:
            None
        Raises:
            IOException
                socket连接异常。
    """
    sendMessage(sock, encoders.PUBLISH_Encoder(0, 0, retain, topic, 0,
                                               message))
    print("[" + getTime() + "]" + " [CLIENT/INFO] Message published at Qos0" +
          ".")
示例#3
0
 def decode(self, data):
     """
         Description:
             对于给定的报文字节串进行解码,并实现对应的逻辑响应。
         Args:
             data(byte[])
                 待解码的报文字节串。
         Returns:
             None
         Raises:
             decoders.IllegalMessageException
                 消息解码错误。
             IOException
                 socket连接错误。
     """
     if data == b'':
         return
     try:
         messageType, results = decoders.message_Decoder(data)
         if messageType == definition.messageType.CONNECT:
             if results['clientId'].isalnum(
             ) and results['clientId'].__len__(
             ) >= 1 and results['clientId'].__len__() <= 23:
                 self.clientId = results['clientId']
                 if checkUser(results['userName'],
                              results['password']) == 2:
                     if results['cleanSession'] == 1:
                         removeSubscribe(results['clientId'])
                     self.keepAlive = results['keepAlive']
                     self.willFlag = results['willFlag']
                     if self.willFlag == 1:
                         self.willTopic = results['willTopic']
                         self.willMessage = results['willMessage']
                         self.willQos = results['willQos']
                         self.willRetain = results['willRetain']
                     print("[" + getTime() + "]" +
                           " [SERVER/INFO] Client " + str(self.address) +
                           " has connected.")
                     sessionPresent = getSubscribe(self.clientId).__len__()
                     if sessionPresent > 0:
                         sessionPresent = 1
                     self.send(
                         encoders.CONNACK_Encoder(
                             sessionPresent,
                             definition.ConnackReturnCode.ACCEPTED))
                     scs = getSubscribe(self.clientId)
                     for sc in scs:
                         for retainedMessage in retainedMessages:
                             if checkFatherSon(
                                     sc[1], retainedMessage['topic']
                             ) or retainedMessage['topic'] == sc[1]:
                                 packetIdentifier = generatePacketIdentifier(
                                 )
                                 print(111)
                                 self.send(
                                     encoders.PUBLISH_Encoder(
                                         0, sc[2], 0,
                                         retainedMessage['topic'],
                                         packetIdentifier,
                                         retainedMessage['message']))
                                 if sc[2] == 2:
                                     timer = threading.Timer(
                                         ACK_TIMEOUT, pubrecNotReceived, [
                                             self,
                                         ])
                                     timeoutTimers.append({
                                         'clientId':
                                         self.getClientId(),
                                         'packetIdentifier':
                                         packetIdentifier,
                                         'waitingFor':
                                         'PUBREC',
                                         'timer':
                                         timer
                                     })
                                     timer.start()
                                 elif sc[2] == 1:
                                     timer = threading.Timer(
                                         ACK_TIMEOUT, pubackNotReceived, [
                                             self,
                                         ])
                                     timeoutTimers.append({
                                         'clientId':
                                         self.getClientId(),
                                         'packetIdentifier':
                                         packetIdentifier,
                                         'waitingFor':
                                         'PUBACK',
                                         'timer':
                                         timer
                                     })
                                     timer.start()
                                 print(
                                     "[" + getTime() + "]" +
                                     " [SERVER/INFO] A retained message sent to Client "
                                     + str(self.address) + " at packet " +
                                     str(packetIdentifier) + " .")
                                 retainedMessages.remove(retainedMessage)
                                 break
                     keepAliveThread = threading.Thread(target=self.counter)
                     keepAliveThread.start()
                 elif checkUser(results['userName'],
                                results['password']) == 0:
                     self.send(
                         encoders.CONNACK_Encoder(
                             0, definition.ConnackReturnCode.
                             REFUSED_INVALID_USER))
                     print("[" + getTime() + "]" +
                           " [SERVER/INFO] Client " + str(self.address) +
                           " has disconnected: Illegal User or Password.")
                     self.onDisconnect()
                 else:
                     self.send(
                         encoders.CONNACK_Encoder(
                             0, definition.ConnackReturnCode.
                             REFUSED_UNAUTHORIZED))
                     print("[" + getTime() + "]" +
                           " [SERVER/INFO] Client " + str(self.address) +
                           " has disconnected: Unauthorized user.")
                     self.onDisconnect()
             else:
                 self.send(
                     encoders.CONNACK_Encoder(
                         0, definition.ConnackReturnCode.
                         REFUSED_ILLEGAL_CLIENTID))
                 print("[" + getTime() + "]" + " [SERVER/INFO] Client " +
                       str(self.address) +
                       " has disconnected: Illegal ClientId.")
                 self.onDisconnect()
         elif messageType == definition.messageType.SUBSCRIBE:
             print("[" + getTime() + "]" + " [SERVER/INFO] Client " +
                   str(self.address) + " subscribing...")
             packetIdentifier = results['packetIdentifier']
             topics = results['topics']
             returnCodes = []
             for i in range(0, topics.__len__()):
                 removeSubscribe(self.clientId, topics[i]['topic'])
                 addSubscribe(self.clientId, topics[i]['topic'],
                              topics[i]['qos'])
                 returnCodes.append(topics[i]['qos'])
             self.send(
                 encoders.SUBACK_Encoder(packetIdentifier, returnCodes))
             print("[" + getTime() + "]" + " [SERVER/INFO] Client " +
                   str(self.address) + " subscribed.")
             print("[" + getTime() + "]" +
                   " [SERVER/INFO] Current subscirbes: " +
                   str(getAllSubscribe()) + " .")
         elif messageType == definition.messageType.UNSUBSCRIBE:
             print("[" + getTime() + "]" + " [SERVER/INFO] Client " +
                   str(self.address) + " unsubscribing...")
             packetIdentifier = results['packetIdentifier']
             topics = results['topics']
             for i in range(0, topics.__len__()):
                 removeSubscribe(self.clientId, topics[i])
             self.send(encoders.UNSUBACK_Encoder(packetIdentifier))
             print("[" + getTime() + "]" + " [SERVER/INFO] Client " +
                   str(self.address) + " unsubscribed.")
             print("[" + getTime() + "]" +
                   " [SERVER/INFO] Current subscirbes: " +
                   str(getAllSubscribe()) + " .")
         elif messageType == definition.messageType.PINGREQ:
             print("[" + getTime() + "]" + " [SERVER/INFO] Client " +
                   str(self.address) + " sent a heartbeat.")
             self.send(encoders.PINGRESP_Encoder())
         elif messageType == definition.messageType.PUBLISH:
             print("[" + getTime() + "]" + " [SERVER/INFO] Client " +
                   str(self.address) + " sent a message.")
             messageQueue.put({
                 'retain': results['retain'],
                 'topic': results['topic'],
                 'message': results['message']
             })
             if results['qos'] == 1:
                 self.send(
                     encoders.PUBACK_Encoder(results['packetIdentifier']))
                 print("[" + getTime() + "]" +
                       " [SERVER/INFO] PUBACK responded to Client " +
                       str(self.address) + " at packet " +
                       str(results['packetIdentifier']) + " .")
             elif results['qos'] == 2:
                 self.send(
                     encoders.PUBREC_Encoder(results['packetIdentifier']))
                 print("[" + getTime() + "]" +
                       " [SERVER/INFO] PUBREC responded to Client " +
                       str(self.address) + " at packet " +
                       str(results['packetIdentifier']) + " .")
         elif messageType == definition.messageType.PUBREL:
             self.send(encoders.PUBCOMP_Encoder(
                 results['packetIdentifier']))
             print("[" + getTime() + "]" +
                   " [SERVER/INFO] PUBCOMP responded to Client " +
                   str(self.address) + " at packet " +
                   str(results['packetIdentifier']) + " .")
         elif messageType == definition.messageType.PUBACK:
             print("[" + getTime() + "]" + " [SERVER/INFO] Client " +
                   str(self.address) + " responded a PUBACK.")
             clientId = self.clientId
             packetIdentifier = results['packetIdentifier']
             try:
                 for i in range(0, timeoutTimers.__len__()):
                     if timeoutTimers[i][
                             'packetIdentifier'] == packetIdentifier and timeoutTimers[
                                 i]['clientId'] == clientId and timeoutTimers[
                                     i]['waitingFor'] == 'PUBACK':
                         timeoutTimers[i]['timer'].cancel()
             except:
                 pass
         elif messageType == definition.messageType.PUBREC:
             print("[" + getTime() + "]" + " [SERVER/INFO] Client " +
                   str(self.address) + " responded a PUBREC.")
             clientId = self.clientId
             packetIdentifier = results['packetIdentifier']
             self.send(encoders.PUBREL_Encoder(packetIdentifier))
             print("[" + getTime() + "]" +
                   " [SERVER/INFO] PUBREL responded to Client " +
                   str(self.address) + " at packet " +
                   str(packetIdentifier) + " .")
             try:
                 for i in range(0, timeoutTimers.__len__()):
                     if timeoutTimers[i][
                             'packetIdentifier'] == packetIdentifier and timeoutTimers[
                                 i]['clientId'] == clientId and timeoutTimers[
                                     i]['waitingFor'] == 'PUBREC':
                         timeoutTimers[i]['timer'].cancel()
                         break
                 timer = threading.Timer(ACK_TIMEOUT,
                                         self.pubcompNotReceived)
                 timeoutTimers.append({
                     'clientId': self.getClientId(),
                     'packetIdentifier': packetIdentifier,
                     'waitingFor': 'PUBCOMP',
                     'timer': timer
                 })
                 timer.start()
             except:
                 pass
         elif messageType == definition.messageType.PUBCOMP:
             print("[" + getTime() + "]" + " [SERVER/INFO] Client " +
                   str(self.address) + " responded a PUBCOMP.")
             clientId = self.clientId
             packetIdentifier = results['packetIdentifier']
             try:
                 for i in range(0, timeoutTimers.__len__()):
                     if timeoutTimers[i][
                             'packetIdentifier'] == packetIdentifier and timeoutTimers[
                                 i]['clientId'] == clientId and timeoutTimers[
                                     i]['waitingFor'] == 'PUBCOMP':
                         timeoutTimers[i]['timer'].cancel()
                         break
             except:
                 pass
         elif messageType == definition.messageType.DISCONNECT:
             self.onDisconnect()
             print("[" + getTime() + "]" + " [SERVER/INFO] Client " +
                   str(self.address) + " has disconnected.")
     except decoders.IllegalMessageException:
         print(data)
         print("[" + getTime() + "]" + " [SERVER/INFO] Client " +
               str(self.address) +
               " has disconnected: Illegal Message Received.")
         self.onDisconnect()
示例#4
0
def publishFromQueue():
    """
        Description:
            从线程安全的messageQueue中按队列顺序发送消息。
        Args:
            None
        Returns:
            None
        Raises:
            IOException
                socket连接异常。
    """
    while True:
        if messageQueue.qsize() != 0:
            messageItem = messageQueue.get()
            subscribers = getSubscribers(messageItem['topic'])
            for i in range(0, subscribers.__len__()):
                subscriber = subscribers[i][0]
                qos = subscribers[i][2]
                connectionsLock.acquire()
                if qos == 0:
                    for j in range(0, connections.__len__()):
                        if connections[j].getClientId() == subscriber:
                            connections[j].send(
                                encoders.PUBLISH_Encoder(
                                    0, qos, 0, messageItem['topic'], 0,
                                    messageItem['message']))
                elif qos == 1:
                    packetIdentifier = generatePacketIdentifier()
                    for j in range(0, connections.__len__()):
                        if connections[j].getClientId() == subscriber:
                            connections[j].send(
                                encoders.PUBLISH_Encoder(
                                    0, qos, 0, messageItem['topic'],
                                    packetIdentifier, messageItem['message']))
                            timer = threading.Timer(ACK_TIMEOUT,
                                                    pubackNotReceived, [
                                                        connections[j],
                                                    ])
                            timeoutTimers.append({
                                'clientId':
                                connections[j].getClientId(),
                                'packetIdentifier':
                                packetIdentifier,
                                'waitingFor':
                                'PUBACK',
                                'timer':
                                timer
                            })
                            timer.start()
                elif qos == 2:
                    packetIdentifier = generatePacketIdentifier()
                    for j in range(0, connections.__len__()):
                        if connections[j].getClientId() == subscriber:
                            connections[j].send(
                                encoders.PUBLISH_Encoder(
                                    0, qos, 0, messageItem['topic'],
                                    packetIdentifier, messageItem['message']))
                            timer = threading.Timer(ACK_TIMEOUT,
                                                    pubrecNotReceived, [
                                                        connections[j],
                                                    ])
                            timeoutTimers.append({
                                'clientId':
                                connections[j].getClientId(),
                                'packetIdentifier':
                                packetIdentifier,
                                'waitingFor':
                                'PUBREC',
                                'timer':
                                timer
                            })
                            timer.start()
                connectionsLock.release()
            if messageItem['retain'] == 1:
                addRetain(messageItem)
            print("[" + getTime() + "]" +
                  " [SERVER/INFO] Queue processed a message." +
                  str(messageQueue.qsize()) + " message(s) in queue, " +
                  str(retainedMessages.__len__()) + " message(s) retained.")