Пример #1
0
 def __init__(self, room_id):
     """初始化服务。
     :params: room_id: 直播间号。
     """
     socket.setdefaulttimeout(20)
     data = RECIEVE_INIT_DATA % room_id
     self.send_data = unhexlify(data)
     self.danmaku_queue = DanmakuQueue(room_id)
     self.is_terminate = False
     self.socket = None
Пример #2
0
def run_recieve(room_id):
    """Run the program of recieving danmakus.

    :param room_id: the id of live room.
    """
    danmaku_queue = DanmakuQueue(room_id)
    try:
        with generate_socket(room_id) as sock:
            produce_danmaku.switch(sock, danmaku_queue, True)
    except RuntimeError and KeyboardInterrupt:
        pass
Пример #3
0
class RecieverService(object):

    """提供弹幕接收服务。
    """

    def __init__(self, room_id):
        """初始化服务。
        :params: room_id: 直播间号。
        """
        socket.setdefaulttimeout(20)
        data = RECIEVE_INIT_DATA % room_id
        self.send_data = unhexlify(data)
        self.danmaku_queue = DanmakuQueue(room_id)
        self.is_terminate = False
        self.socket = None

    def cmd_run(self):
        """启动服务(只针对命令行使用)"""
        thread.start_new_thread(self.subscribe_danmaku, ())
        self.consume_danmaku()

    def recieve_danmaku(self):
        """接收一个弹幕"""
        return self.danmaku_queue.dequeue()

    def consume_danmaku(self):
        """获取接收到的弹幕。"""
        while True:
            if self.is_terminate:
                break
            danmaku = self.recieve_danmaku()
            if danmaku:
                print danmaku

    def subscribe_danmaku(self):
        """订阅接收到的弹幕。"""
        is_first = True
        print "请求服务器连接。"
        retry_time = 0
        while True:
            try:
                self.socket = socket.socket(socket.AF_INET,
                                            socket.SOCK_STREAM)
                self.socket.connect(
                    (RECIEVE_SERVER_ADDRESS, RECIEVE_SERVER_PORT))
                self.socket.sendall(self.send_data)
            except socket.error:
                if retry_time == 5:
                    print "重试请求过多,服务中止!"
                    self.is_terminate = True
                    break
                print "服务器连接失败..."
                retry_time += 1
                time.sleep(4)
                continue
            if is_first:
                print "开始接收弹幕。(Ctrl + C 退出)"
                is_first = False
            retry_time = 0
            self.get_danmaku()

    def heartbeat(self):
        string = '01020004'
        send_data = unhexlify(string)
        self.socket.sendall(send_data)

    def get_danmaku(self):
        """ 请求获得弹幕信息。"""
        start = time.time()
        is_heath = True
        while True:
            end = time.time()
            if end - start > 10:
                start = time.time()
                try:
                    self.heartbeat()
                except socket.error:
                    is_heath = False
            try:
                data = self.socket.recv(2)
                if not data:
                    self.socket.close()
                    break
            except socket.timeout:
                if not is_heath:
                    print "连接超时,准备重连服务器。。。"
                    break
            except socket.error:
                break
            data_type = convert_hexascii_to_int(data)
            if data_type == 1:
                count = convert_hexascii_to_int(self.socket.recv(4))
                if self.danmaku_queue.set_count(count):
                    print "当前直播人数为:{0}".format(count)
            elif data_type == 4:
                length = convert_hexascii_to_int(self.socket.recv(2)) - 4
                if length > 0:
                    msg = self.socket.recv(length)
                    self.store_message(json.loads(msg))

    def store_message(self, msg):
        """将信息存入弹幕队列中

        :params: msg: 从服务器获取到的消息。
        """
        recieved_time = datetime.now().strftime(TIME_FORMAT)
        try:
            danmaku = DanmakuModel(
                publisher=msg['info'][2][1],
                content=msg['info'][1],
                recieved_time=recieved_time
            )
            self.danmaku_queue.enqueue(danmaku)
        except Exception:
            # b站现在新推出了msg类型,防止问题先pass,之后来处理这些新弹幕
            pass