python - How to create a websocket client by using QWebSocket in PyQt5 -
i want create websocket client using qwebsocket in pyqt5.for convenience, assume have websocket server, source code ,
from pyqt5 import qtcore, qtwebsockets, qtnetwork, qtgui pyqt5.qtwidgets import qapplication, qmainwindow, qmenu, qaction pyqt5.qtcore import qurl class myserver(qtcore.qobject): def __init__(self, parent): super(qtcore.qobject, self).__init__(parent) self.clients = [] self.server = qtwebsockets.qwebsocketserver(parent.servername(), parent.securemode(), parent) if self.server.listen(qtnetwork.qhostaddress.localhost, 1302): print('connected: '+self.server.servername()+' : ' +self.server.serveraddress().tostring()+':'+str(self.server.serverport())) else: print('error') self.server.newconnection.connect(self.onnewconnection) self.clientconnection = none print(self.server.islistening()) def onnewconnection(self): self.clientconnection = self.server.nextpendingconnection() self.clientconnection.textmessagereceived.connect(self.processtextmessage) self.clientconnection.binarymessagereceived.connect(self.processbinarymessage) self.clientconnection.disconnected.connect(self.socketdisconnected) print("newclient") self.clients.append(self.clientconnection) def processtextmessage(self, message): print(message) if self.clientconnection: client in self.clients: # if client!= self.clientconnection: client.sendtextmessage(message) # self.clientconnection.sendtextmessage(message) def processbinarymessage(self, message): print("b:",message) if self.clientconnection: self.clientconnection.sendbinarymessage(message) def socketdisconnected(self): if self.clientconnection: self.clients.remove(self.clientconnection) self.clientconnection.deletelater() if __name__ == '__main__': import sys app = qapplication(sys.argv) serverobject = qtwebsockets.qwebsocketserver('my socket', qtwebsockets.qwebsocketserver.nonsecuremode) server = myserver(serverobject) serverobject.closed.connect(app.quit) app.exec_()
it can create websocket server,and test using javascript,it works fine .but can find way create client using qwebsocket.my client code this:
client = qtwebsockets.qwebsocket("",qtwebsockets.qwebsocketprotocol.version13,none) client.open(qurl("ws://127.0.0.1:1302")) client.sendtextmessage("asd") client.close()
it seems server did not receive message sent client,how create websocket client , send message using qwebsocket?
this typical problem qt console programs, need call client methods outside of python constructor (__init__
).
i modified server little bit, adding error tests (nothing new):
from pyqt5 import qtcore, qtwebsockets, qtnetwork, qtgui pyqt5.qtwidgets import qapplication, qmainwindow, qmenu, qaction pyqt5.qtcore import qurl class myserver(qtcore.qobject): def __init__(self, parent): super(qtcore.qobject, self).__init__(parent) self.clients = [] print("server name: {}".format(parent.servername())) self.server = qtwebsockets.qwebsocketserver(parent.servername(), parent.securemode(), parent) if self.server.listen(qtnetwork.qhostaddress.localhost, 1302): print('listening: {}:{}:{}'.format( self.server.servername(), self.server.serveraddress().tostring(), str(self.server.serverport()))) else: print('error') self.server.accepterror.connect(self.onaccepterror) self.server.newconnection.connect(self.onnewconnection) self.clientconnection = none print(self.server.islistening()) def onaccepterror(accept_error): print("accept error: {}".format(accept_error)) def onnewconnection(self): print("onnewconnection") self.clientconnection = self.server.nextpendingconnection() self.clientconnection.textmessagereceived.connect(self.processtextmessage) self.clientconnection.textframereceived.connect(self.processtextframe) self.clientconnection.binarymessagereceived.connect(self.processbinarymessage) self.clientconnection.disconnected.connect(self.socketdisconnected) print("newclient") self.clients.append(self.clientconnection) def processtextframe(self, frame, is_last_frame): print("in processtextframe") print("\tframe: {} ; is_last_frame: {}".format(frame, is_last_frame)) def processtextmessage(self, message): print("processtextmessage - message: {}".format(message)) if self.clientconnection: client in self.clients: # if client!= self.clientconnection: client.sendtextmessage(message) # self.clientconnection.sendtextmessage(message) def processbinarymessage(self, message): print("b:",message) if self.clientconnection: self.clientconnection.sendbinarymessage(message) def socketdisconnected(self): print("socketdisconnected") if self.clientconnection: self.clients.remove(self.clientconnection) self.clientconnection.deletelater() if __name__ == '__main__': import sys app = qapplication(sys.argv) serverobject = qtwebsockets.qwebsocketserver('my socket', qtwebsockets.qwebsocketserver.nonsecuremode) server = myserver(serverobject) serverobject.closed.connect(app.quit) app.exec_()
the client uses qtimer
call required methods outside of __init__
method. added ping / pong methods check connection :
import sys pyqt5 import qtcore, qtwebsockets, qtnetwork pyqt5.qtcore import qurl, qcoreapplication, qtimer pyqt5.qtwidgets import qapplication class client(qtcore.qobject): def __init__(self, parent): super().__init__(parent) self.client = qtwebsockets.qwebsocket("",qtwebsockets.qwebsocketprotocol.version13,none) self.client.error.connect(self.error) self.client.open(qurl("ws://127.0.0.1:1302")) self.client.pong.connect(self.onpong) def do_ping(self): print("client: do_ping") self.client.ping(b"foo") def send_message(self): print("client: send_message") self.client.sendtextmessage("asd") def onpong(self, elapsedtime, payload): print("onpong - time: {} ; payload: {}".format(elapsedtime, payload)) def error(self, error_code): print("error code: {}".format(error_code)) print(self.client.errorstring()) def close(self): self.client.close() def quit_app(): print("timer timeout - exiting") qcoreapplication.quit() def ping(): client.do_ping() def send_message(): client.send_message() if __name__ == '__main__': global client app = qapplication(sys.argv) qtimer.singleshot(2000, ping) qtimer.singleshot(3000, send_message) qtimer.singleshot(5000, quit_app) client = client(app) app.exec_()
server output:
g:\qt\qttests>python so_qwebsocket_server.py server name: socket listening: socket:127.0.0.1:1302 true onnewconnection newclient in processtextframe frame: asd ; is_last_frame: true processtextmessage - message: asd socketdisconnected
client output:
g:\qt\qttests>python so_qwebsocket_client.py client: do_ping onpong - time: 0 ; payload: b'foo' client: send_message timer timeout
all in all, if use client in simple gui (e.g. moving client.sendtextmessage()
outside __init__
, connecting button click send message), due asynchronous nature, should work without problems!
Comments
Post a Comment