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()

Reply With Quote

