Socket Thread и PyGTK - PullRequest
       14

Socket Thread и PyGTK

3 голосов
/ 15 декабря 2010

Я пытаюсь написать программу для обмена мгновенными сообщениями, основной пользовательский интерфейс почти закончен, и я изучаю принимающую часть сообщений.У меня есть класс интерфейса и многопоточный класс Receive_Socket.Каждый раз, когда сокет класса Received_Socket получает сообщение, он выполняет gobject.idle_add () для вызова метода пользовательского интерфейса для отображения сообщения в окне чата.После строки gobject.idle.add () у меня есть цикл while, который повторяется до тех пор, пока сообщение фактически не отобразится в окне чата (я хочу, чтобы сообщение отображалось до получения другого сообщения, потому что я прочитал этот gobject.idle_add ()не гарантирует порядок выполнения, и, конечно, я хочу, чтобы сообщения отображались по порядку :))

Я попытался суммировать свой код:

Класс пользовательского интерфейса:

Class UI:
##### somewhere in the init #####
    self.message_status = 0
def chat_window(self, contact, message=0):
    Check if a chat window is opened for the contact, if not it opens one.
    => In reality this check if a gtk.Window containing a gtk.Notebook is opened, 
    => if not it opens one
    => Then it creates a page for the contact in the notebook, containing a 
    => gtk.Textview which displays messages
    if message:
        self.message_display(contact, message)
def message_display(self,a,b):
    => Display the message in the message in the contact's textview
    self.message_status = 1

Потоковый класс Receive_Socket:

Class Receive_Socket(threading.thread):
    message = sock.recv(1024)
    => the sender name is written in the message 
    if message:
        gobject.idle_add(myui.chat_window,sender, message)
        while not myui.message_status:
            time.sleep(0.1)
        myui.message_status = 0

Основной код:

if __name__ == "__main__":
    myui = UI()
    reception = Receive_Socket()
    reception.start()
    gtk.main()

Мои вопросы:

1) Этот код кажется эффективным?Является ли это (наличие многопоточного получающего класса вместе с моим классом пользовательского интерфейса) лучшим способом для продолжения?

2) К моменту отображения сообщения сокет может получить 2 или более сообщений, поэтому, когда это происходитmessage = sock.recv (1024), несколько сообщений будут объединены в переменное сообщение.Я думал о включении длины сообщения в каждое сообщение, поэтому, если в 1024 байтах содержится более 1 сообщения, он возьмет сообщение и поместит остаток в переменную message_buffer, а перед повторным выполнением sock.recv (1024) он проверит,переменная message_buffer содержит что-нибудь, и если так, поместите message_buffer в переменную message вместо sock.recv (1024).Есть ли более легкое / лучшее решение для этого?

Заранее спасибо,

Nolhian

1 Ответ

3 голосов
/ 15 декабря 2010
  1. Нет.Не используйте темы.Вместо этого используйте glib.io_add_watch, чтобы сам gtk / glib вызывал вашу функцию, когда сокет готов к чтению.Таким образом, вы не заморозите свой графический интерфейс и не будете нуждаться в потоках.Вам также не понадобится idle_add.

  2. Если вы выполните 1 , у вас не возникнет этой проблемы, так как сообщения будут приходить по порядку и будутне быть параллельными потоками, чтобы запутать данные.

...