Skip to content

Instantly share code, notes, and snippets.

@petrasovaa
Last active March 2, 2020 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petrasovaa/1dcc751c2759d3813641b64ed5970fd6 to your computer and use it in GitHub Desktop.
Save petrasovaa/1dcc751c2759d3813641b64ed5970fd6 to your computer and use it in GitHub Desktop.
Desktop wxPython chat application prototype chatting with Django Channels tutorial chat room
import wx
from wxasync import AsyncBind, WxAsyncApp, StartCoroutine
import asyncio
from asyncio.events import get_event_loop
import websockets
import logging
import sys
import json
logger = logging.getLogger(__name__)
logging.basicConfig(
stream=sys.stdout,
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
def callback_fn(data, *args, **kwargs):
# Write here your logic
logger.debug('This is the callback speaking!') # ignore data
class WSClient():
def __init__(self, url, callback=None):
self.url = url
self.ws = None
self.callback = callback
async def connect(self):
'''
Connecting to webSocket server
websockets.client.connect returns a WebSocketClientProtocol, which is used to send and receive messages
'''
logger.debug('Creating new connection...')
self.ws = await websockets.client.connect(self.url)
if self.ws.open:
logger.debug('Connection stablished. Client correcly connected')
async def receiveMessage(self):
'''
Receiving all server messages and handling them
'''
while True:
logger.debug('receiveMessage')
await asyncio.sleep(0.5)
if self.ws and self.ws.open:
try:
message = await self.ws.recv()
logger.debug('Server said > {}'.format(message))
if self.callback:
message = json.loads(message)
self.callback(message['message'])
except websockets.exceptions.ConnectionClosed:
logger.debug('Connection with server closed')
break
async def sendMessage(self, message):
try:
await self.ws.send('{{"message": "{m}" }}'.format(m=message))
except websockets.exceptions.ConnectionClosed:
logger.debug('Connection with server closed')
class TestFrame(wx.Frame):
def __init__(self, parent=None):
super(TestFrame, self).__init__(parent)
vbox = wx.BoxSizer(wx.VERTICAL)
self.text_ctrl = wx.TextCtrl(self)
button1 = wx.Button(self, label="Submit")
self.chatCtrl = wx.TextCtrl(self, value="", style=wx.TE_MULTILINE)
vbox.Add(self.chatCtrl, proportion=1, border=2, flag=wx.EXPAND|wx.ALL)
vbox.Add(self.text_ctrl, proportion=0, border=2, flag=wx.EXPAND|wx.ALL)
vbox.Add(button1, proportion=0, border=2, flag=wx.EXPAND|wx.ALL)
self.SetSizer(vbox)
self.Layout()
button1.Bind(wx.EVT_BUTTON, self.submit)
self.ws_client = WSClient(url='ws://127.0.0.1:8000/ws/chat/lobby/', callback=self.callback_fn)
StartCoroutine(self.ws_client.connect, self)
StartCoroutine(self.ws_client.receiveMessage, self)
def callback_fn(self, message):
self.chatCtrl.write(message + '\n')
def submit(self, event):
message = self.text_ctrl.GetValue()
StartCoroutine(self.ws_client.sendMessage(message), self)
self.text_ctrl.SetValue('')
app = WxAsyncApp()
frame = TestFrame()
frame.Show()
app.SetTopWindow(frame)
loop = get_event_loop()
loop.run_until_complete(app.MainLoop())
'''
async def listen_forever(self):
logger.debug('Creating new connection...')
try:
async with websockets.connect(self.url) as ws:
logger.debug(str(type(self.ws)))
while True:
# listener loop
if self.message:
await ws.send('{{"message": "{m}" }}'.format(m=self.message))
logger.debug('Client sent > {}'.format(self.message))
self.message = ''
try:
reply = await asyncio.wait_for(ws.recv(), timeout=self.reply_timeout)
except (asyncio.TimeoutError, websockets.exceptions.ConnectionClosed):
try:
pong = await ws.ping()
await asyncio.wait_for(pong, timeout=self.ping_timeout)
logger.debug('Ping OK, keeping connection alive...')
continue
except:
logger.debug(
'Ping error - retrying connection in {} sec (Ctrl-C to quit)'.format(self.sleep_time))
await asyncio.sleep(self.sleep_time)
break
logger.debug('Server said > {}'.format(reply))
if self.callback:
self.callback(reply)
except socket.gaierror:
logger.debug(
'Socket error - retrying connection in {} sec (Ctrl-C to quit)'.format(self.sleep_time))
except ConnectionRefusedError:
logger.debug('Nobody seems to listen to this endpoint. Please check the URL.')
'''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment