|
@@ -39,15 +39,6 @@ lcchat = logging.getLogger(__name__+".client.chat")
|
|
|
|
|
|
_tasks = []
|
|
_tasks = []
|
|
|
|
|
|
-def _append_task():
|
|
|
|
- cur_task = curio.current_task()
|
|
|
|
- _tasks.append(cur_task)
|
|
|
|
-
|
|
|
|
-def _remove_task():
|
|
|
|
- cur_task = curio.current_task()
|
|
|
|
- if cur_task in _tasks:
|
|
|
|
- _tasks.remove(cur_task)
|
|
|
|
-
|
|
|
|
class ConnHandlerBase(object):
|
|
class ConnHandlerBase(object):
|
|
def __init__(self, socket, addr, server):
|
|
def __init__(self, socket, addr, server):
|
|
self.status = "init"
|
|
self.status = "init"
|
|
@@ -437,6 +428,10 @@ class Client(threading.Thread):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
class AsyncClient(object):
|
|
class AsyncClient(object):
|
|
"""docstring for Client"""
|
|
"""docstring for Client"""
|
|
is_connecting = False
|
|
is_connecting = False
|
|
@@ -463,6 +458,7 @@ class AsyncClient(object):
|
|
self.error_handler = error_handler
|
|
self.error_handler = error_handler
|
|
self.socket = None
|
|
self.socket = None
|
|
self.status = "disconnected"
|
|
self.status = "disconnected"
|
|
|
|
+
|
|
def connect(self):
|
|
def connect(self):
|
|
self.status = "connecting"
|
|
self.status = "connecting"
|
|
self.socket = self.make_socket()
|
|
self.socket = self.make_socket()
|
|
@@ -473,11 +469,6 @@ class AsyncClient(object):
|
|
self.socket.connect((self.host, self.port))
|
|
self.socket.connect((self.host, self.port))
|
|
elif self.af_family == "AF_UNIX":
|
|
elif self.af_family == "AF_UNIX":
|
|
self.socket.connect(self.host)
|
|
self.socket.connect(self.host)
|
|
- # if os.path.exists(self.host):
|
|
|
|
- # pass
|
|
|
|
- # else:
|
|
|
|
- # lclient.warn("File not found. Aborting.")
|
|
|
|
- # return
|
|
|
|
self.is_connected = True
|
|
self.is_connected = True
|
|
self.status = "connected"
|
|
self.status = "connected"
|
|
lclient.info("connected")
|
|
lclient.info("connected")
|
|
@@ -488,6 +479,7 @@ class AsyncClient(object):
|
|
lclient.info("failed to connect to socket '{}'".format(self.host))
|
|
lclient.info("failed to connect to socket '{}'".format(self.host))
|
|
self.disconnect()
|
|
self.disconnect()
|
|
return False
|
|
return False
|
|
|
|
+
|
|
def disconnect(self):
|
|
def disconnect(self):
|
|
lclient.info("disconnecting from socket '{}'".format(self.host))
|
|
lclient.info("disconnecting from socket '{}'".format(self.host))
|
|
self.is_connected = False
|
|
self.is_connected = False
|
|
@@ -504,6 +496,7 @@ class AsyncClient(object):
|
|
"maybe it is already closed",exc_info=e)
|
|
"maybe it is already closed",exc_info=e)
|
|
del self.socket
|
|
del self.socket
|
|
self.socket = None
|
|
self.socket = None
|
|
|
|
+
|
|
def handle_data(self, data_received):
|
|
def handle_data(self, data_received):
|
|
data_decoded = data_received.decode("utf-8")
|
|
data_decoded = data_received.decode("utf-8")
|
|
lcchat.info("Server: "+data_decoded)
|
|
lcchat.info("Server: "+data_decoded)
|
|
@@ -512,8 +505,10 @@ class AsyncClient(object):
|
|
self.handle_data_func(data_decoded)
|
|
self.handle_data_func(data_decoded)
|
|
except Exception as e:
|
|
except Exception as e:
|
|
lclient.error(e, exc_info=True)
|
|
lclient.error(e, exc_info=True)
|
|
|
|
+
|
|
def is_running(self):
|
|
def is_running(self):
|
|
return (self in threading.enumerate())
|
|
return (self in threading.enumerate())
|
|
|
|
+
|
|
def make_socket(self):
|
|
def make_socket(self):
|
|
lclient.info("creating a {} socket".format(self.af_family))
|
|
lclient.info("creating a {} socket".format(self.af_family))
|
|
if self.af_family == "AF_INET":
|
|
if self.af_family == "AF_INET":
|
|
@@ -527,58 +522,53 @@ class AsyncClient(object):
|
|
)
|
|
)
|
|
)
|
|
)
|
|
return s
|
|
return s
|
|
- def main_loop(self):
|
|
|
|
|
|
+
|
|
|
|
+ async def read_from_socket(self):
|
|
|
|
+ data_received = await self.socket.recv(self.block_size)
|
|
|
|
+ return data_received
|
|
|
|
+
|
|
|
|
+ async def recv(self):
|
|
|
|
+ data_received = await self.socket.recv(self.block_size)
|
|
|
|
+ data_decoded = data_received.decode("utf-8")
|
|
|
|
+ return data_decoded
|
|
|
|
+
|
|
|
|
+ async def run(self):
|
|
lclient.debug("starting main loop")
|
|
lclient.debug("starting main loop")
|
|
while ( not self.exit_event ):
|
|
while ( not self.exit_event ):
|
|
if not self.status in ["connected"]:
|
|
if not self.status in ["connected"]:
|
|
time.sleep(0.1)
|
|
time.sleep(0.1)
|
|
continue
|
|
continue
|
|
- # print(0)
|
|
|
|
- read_confirmed, write_confirmed, exc_confirmed \
|
|
|
|
- = select.select(
|
|
|
|
- [self.socket],
|
|
|
|
- [],
|
|
|
|
- [self.socket],
|
|
|
|
- 1
|
|
|
|
- )
|
|
|
|
- if self.socket in exc_confirmed:
|
|
|
|
- self.is_connected = False
|
|
|
|
- lclient.warning("socket is expected to corrupt, exiting")
|
|
|
|
- self.disconnect()
|
|
|
|
- # self.stop()
|
|
|
|
- break
|
|
|
|
- elif self.socket in read_confirmed:
|
|
|
|
- try:
|
|
|
|
- data_received = self.read_from_socket()
|
|
|
|
- if data_received == b'':
|
|
|
|
- lclient.info("connection is broken, closing socket exiting")
|
|
|
|
- self.disconnect()
|
|
|
|
- # self.stop()
|
|
|
|
- # break
|
|
|
|
- else:
|
|
|
|
- self.handle_data(data_received)
|
|
|
|
- except Exception as e:
|
|
|
|
- lclient.error(e, exc_info=True)
|
|
|
|
- if type(e) is OSError:
|
|
|
|
- self.is_connected = False
|
|
|
|
- lclient.warn("connection broken, exiting")
|
|
|
|
- self.disconnect()
|
|
|
|
- # self.stop()
|
|
|
|
- # break
|
|
|
|
- else:
|
|
|
|
- raise
|
|
|
|
- else:
|
|
|
|
- time.sleep(0.1)
|
|
|
|
- def read_from_socket(self):
|
|
|
|
- data_received = self.socket.recv(self.block_size)
|
|
|
|
- return data_received
|
|
|
|
- def run(self,connect=False):
|
|
|
|
|
|
+ # if self.socket in exc_confirmed:
|
|
|
|
+ # self.is_connected = False
|
|
|
|
+ # lclient.warning("socket is expected to corrupt, exiting")
|
|
|
|
+ # self.disconnect()
|
|
|
|
+ # # self.stop()
|
|
|
|
+ # break
|
|
|
|
+ # elif self.socket in read_confirmed:
|
|
|
|
+ try:
|
|
|
|
+ data = await self.read_from_socket()
|
|
|
|
+ if not data:
|
|
|
|
+ lclient.info("connection closed")
|
|
|
|
+ self.disconnect()
|
|
|
|
+ else:
|
|
|
|
+ self.handle_data(data)
|
|
|
|
+ except Exception as e:
|
|
|
|
+ lclient.error(e, exc_info=True)
|
|
|
|
+ if type(e) is OSError:
|
|
|
|
+ self.is_connected = False
|
|
|
|
+ lclient.warn("connection broken, exiting")
|
|
|
|
+ self.disconnect()
|
|
|
|
+ else:
|
|
|
|
+ raise
|
|
|
|
+
|
|
|
|
+ async def start(self,connect=False):
|
|
if connect:
|
|
if connect:
|
|
self.connect()
|
|
self.connect()
|
|
if self.error_handler:
|
|
if self.error_handler:
|
|
- self.error_handler(self.main_loop)
|
|
|
|
|
|
+ self.error_handler(self.run)
|
|
else:
|
|
else:
|
|
- self.main_loop()
|
|
|
|
|
|
+ self.run()
|
|
|
|
+
|
|
def send(self, msg):
|
|
def send(self, msg):
|
|
msg = msg.rstrip()
|
|
msg = msg.rstrip()
|
|
msg_encoded = bytes(msg+"\r\n", "utf-8")
|
|
msg_encoded = bytes(msg+"\r\n", "utf-8")
|
|
@@ -588,9 +578,13 @@ class AsyncClient(object):
|
|
except Exception as e:
|
|
except Exception as e:
|
|
self.is_connected = False
|
|
self.is_connected = False
|
|
lclient.error(e, exc_info=True)
|
|
lclient.error(e, exc_info=True)
|
|
- self.status = "shutdown"
|
|
|
|
|
|
+ self.disconnect()
|
|
|
|
+ # self.exit_event = True
|
|
|
|
+ # self.status = "shutdown"
|
|
|
|
+
|
|
def setup(self):
|
|
def setup(self):
|
|
pass
|
|
pass
|
|
|
|
+
|
|
def stop(self,reason=None):
|
|
def stop(self,reason=None):
|
|
self.disconnect()
|
|
self.disconnect()
|
|
self.exit_event = True
|
|
self.exit_event = True
|