我试图写一个即时消息程序,基本的用户界面几乎完成,我正在寻找消息的接收部分。我有一个UI类和一个线程化的Receive_Socket类。每当Received_Socket类的套接字接收到消息时,它都会执行gobject.idle_add()来调用UI方法,以便将消息显示在聊天窗口中。在gobject.idle.add()行之后,我有一个while循环,它循环直到消息实际上显示在聊天窗口中(我希望在接收另一条消息之前显示消息,因为我读取了gobject.idle_add()不保证执行顺序,当然我想按顺序显示的消息:))套接字线程和PyGTK
我想总结一下我的代码:
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
螺纹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字节中有多条消息,它将接收消息并将其余消息放入一个message_buffer变量中,并在再次执行sock.recv(1024)之前检查是否message_buffer变量包含任何内容,如果是,则将message_buffer放入消息变量中,而不是sock.recv(1024)。有没有更容易/更好的解决方案来做到这一点?
由于提前,
Nolhian
谢谢它真的很好!只是关于2)的一个问题,glib.io_add_watch如何真正起作用?例如,我向套接字发送了3条消息,当它接收到第一条消息时,它会调用写在glib.io_add_watch中的回调函数,但在处理回调函数时,其他2条消息将被套接字接收,因此,当回调完成时返回True),它会看到套接字有数据并再次启动回调,但这次fd.recv(1024)将包含连接的2条消息,不是吗? – Nolhian 2010-12-15 23:20:49
@Nolhian:当然,你的协议在消息之间肯定有某种分隔符。所以你必须自己拆分消息,并使用缓冲区来保留部分消息,直到消息的其余部分尚未到达。另一种选择是使用'twisted' http://twistedmatrix.com/这是一个网络框架。它的主循环与gtk主循环兼容。 – nosklo 2010-12-16 04:35:51
@nosklo:可以使用'glib。io_add_watch'绑定的套接字等待侦听? – Hibou57 2014-02-13 06:11:40