我正在尝试编写即时消息程序,基本的ui几乎已经完成,我正在查看消息的接收部分。我有一个UI类和一个线程Receive_Socket类。每次Received_Socket类的套接字接收消息时,它都会执行gobject.idle_add()来调用UI方法,以便将消息显示在聊天窗口中。在gobject.idle.add()行之后,我有一个while循环,它循环直到消息实际显示在聊天窗口中(我希望在收到另一条消息之前显示消息,因为我读了gobject.idle_add()不保证执行顺序,当然我希望消息按顺序显示:))
我试着总结一下我的代码:
UI类:
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
Threaded 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)这种代码看起来效率如何?是(具有线程接收类和我的UI类)是最好的方法吗?
2)当消息显示时,套接字可能已收到2条或更多消息,因此当它再次发出message = sock.recv(1024)时,将在变量消息中连接多条消息。我想在每条消息中包含消息长度,所以如果1024字节中有超过1条消息,它将接收消息并将其余消息放入message_buffer变量中,然后在再次执行sock.recv(1024)之前检查是否message_buffer变量包含任何内容,如果是,则将message_buffer放在消息变量而不是sock.recv(1024)中。有没有更简单/更好的解决方案呢?
提前致谢,
Nolhian
答案 0 :(得分:3)
没有。不要使用线程。相反,当套接字准备好读取时,使用glib.io_add_watch
使gtk / glib本身调用你的函数。这样你就不会冻结你的gui而且不需要线程。您也不需要idle_add
。
如果您执行 1 ,则不会出现此问题,因为邮件将按顺序到达,并且没有并发线程可以混淆数据。