×

Discussion Board

Results 1 to 4 of 4
  1. #1
    Registered User
    Join Date
    Jun 2005
    Posts
    5

    Question Socket and thread issues with UI programming

    Hi there,

    I've had a good, but frustrating, weekend trying to do a bit of client / server socket communication betweem my phone and my pc.

    I am trying to write an app (similar to something described in the PyS60 documentation) that has a UI in the main thread and a socket listening in another thread. When the listening thread receives information it should notify the UI via a callback. I have studied both the rssreader.py example and the applicationskeleton example.py to lead where I am going

    The problem i have is that once the connection has been made (and despite launching a new thread for this purpose) the UI no longer responds (to either softkeys) and I can't exit the application. I end up having to restart my phone to regain control (I can't run under an emulator as the connection is over bluetooth and I am connecting to a machine not supported by Nokias emulators :-(.

    I have done a number of google searches and whilst the PythonGotchas page (on the post neo wiki) has a topic called Series60Threading, the resultant page has been spammed and there is no useful information.

    Can someone take a look below and let me know what I am doing wrong. In my head I am either getting my socket programming mixed up or I have forgotten how to do threading as I have been using J2EE containers for too long!

    Thanks in advance and thanks for producing something that has let me lose my weekend :-)

    Code:
    import e32
    import appuifw, socket
    
    commands = {1:'hello'}
    
    class UnSunkClientListener:
    	def __init__(self, target):
    		self.lock=e32.Ao_lock()
    		self.callbacks=[]
    		self.target = target
    		self.soc = socket.socket(socket.AF_BT, socket.SOCK_STREAM)
    		
    	def registerCallback(self, callback):
    		self.callbacks.append(callback)
    		
    	def _notifyCallbacks(self, *args):
    		for x in self.callbacks:
    			x(*args)
    		
    	def _process(self):
    		while 1:
    			op = self.soc.recv(1)
    			print op
    		
    	def connect(self):
    		self.soc.connect(self.target)
    		import thread
    		if e32.is_ui_thread() == True:
    			self.t = thread.start_new_thread(self._process, ())
    
    	def disconnect(self):
    		self.t.exit()
    		self.soc.disconnect()
    
    class UnSunkClientUI:
    	def __init__(self):
    		self.lock = e32.Ao_lock()
    		self.exitFlag=False
    		self.oldExitKeyHandler=appuifw.app.exit_key_handler
    		self.oldAppBody=appuifw.app.body
    		self.oldTitle=appuifw.app.title
    		appuifw.app.title=u'UnSunk Client'
    		appuifw.app.exit_key_handler = self.abort
    		appuifw.app.menu=[(u"Connect...", self.connect)]
    		
    	def run(self):
    		try:
    			self.lock.wait()
    			while not self.exitFlag:
    				self.refresh()
    				self.lock.wait()
    		finally:
    			self.close()
    			
    	def close(self):
    		appuifw.app.menu = []
    		appuifw.app.body = self.oldAppBody
    		appuifw.app.exit_key_handler = self.oldExitKeyHandler
    		appuifw.app.title = self.oldTitle
    
    	def notify(self, context):
    		#invoked when action happens from the listener
    		self.lock.signal()
    		pass
    		
    	def refresh(self):
    		#update UI following an update
    		pass
    		
    	def connect(self):
    		address,services=socket.bt_discover()
    		if len(services)>1:
    			choices=services.keys()
    			choices.sort()
    			choice=appuifw.popup_menu([unicode(services[x])+": "+x for x in choices],u'Choose port:')
    			target=(address,services[choices[choice]])
    		else:
    			target=(address,services.values()[0])
    		self.listener = UnSunkClientListener(target)
    		self.listener.registerCallback(self.notify)
    		self.listener.connect()
    		appuifw.app.menu=[(u"Disconnect", self.disconnect),(u"Exit", self.abort)]
    		
    	def disconnect(self):
    		self.listener.disconnect()
    		appuifw.app.menu=[(u"Connect...", self.connect)]
    		
    	def abort(self):
    		# Exit-key handler.
    		self.exitFlag = True
    		self.lock.signal()
    		
    
    def main():
        client = UnSunkClientUI()
        client.run()
    
    if __name__ == "__main__":
        main()

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    5

    Follow up

    Ok, so I didn't seem to get much response to this ;-) Therefore I'll ask the question in another way, does anyone have any examples (other than the rssreader or applicationskeleton) that shows threading and socket interaction?

    Alternatively, what documentation can I read as I am obviously mis understanding what is in the documentation bundled with the Python release.

    Thanks in advance

    M

  3. #3
    Registered User
    Join Date
    Feb 2005
    Posts
    10
    Your listener class creates a socket in one thread and then tries to receive from it in another. This is not allowed; you can't share file descriptors between threads.

    -Ken

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    5

    Many thanks

    Ken,

    Thanks for the tip, I'll re-structure the code and see what happens next.

    M

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×