diff --git a/ahserver/processorResource.py b/ahserver/processorResource.py index 087e800..9a61923 100755 --- a/ahserver/processorResource.py +++ b/ahserver/processorResource.py @@ -395,26 +395,35 @@ class ProcessorResource(AppLogger, StaticResource,Url2File): return None def websocketUrl(self, request, url): + url = entireUrl(request, url) if url.startswith('https'): return 'wss' + url[5:] return 'ws' + url[4:] + def urlWebsocketify(self, url): + if url.endswith('.ws') or url.endswith('.wss'): + if url.startswith('https'): + return 'wss' + url[5:] + return 'ws' + url[4:] + return url def entireUrl(self, request, url): + ret_url = '' if url.startswith('http://') or \ url.startswith('https://') or \ url.startswith('ws://') or \ url.startswith('wss://'): - return url - if url.startswith('/'): + ret_url = url + elif url.startswith('/'): u = f'{self._preurl}{url}' # print(f'entireUrl(), {u=}, {url=}, {self._preurl=}') - return u - path = request.path - p = self.relatedurl(path,url) - u = f'{self._preurl}{p}' - # print(f'entireUrl(), {u=}, {url=}, {self._preurl=}') - return u + ret_url = u + else: + path = request.path + p = self.relatedurl(path,url) + u = f'{self._preurl}{p}' + ret_url = u + return self.urlWebsocketify(ret_url) def url2path(self, url): if url.startswith(self._preurl): diff --git a/ahserver/websocketProcessor.py b/ahserver/websocketProcessor.py index 46550ae..aed9cec 100755 --- a/ahserver/websocketProcessor.py +++ b/ahserver/websocketProcessor.py @@ -78,90 +78,94 @@ class XtermProcessor(BaseProcessor): self.sshnode.close() self.p_obj.close() +async def ws_send(ws:web.WebSocketResponse, data): + data = { + "type":1, + "data":data + } + return await ws.send_str(json.dumps(data)) + class WsPool: - def __init__(self, ws_path, app): + def __init__(self, ws, ws_path, app): self.app = app self.id = None + self.ws = ws + print(f'-----------{self.id=}-----------') self.ws_path = ws_path - self.data = self.get_data() - if self.data is None: - self.data = {} - self.set_data() def get_data(self): - self.data = self.app.get_data(self.ws_path) - - def set_data(self): - self.app.set_data(self.ws_path, self.data) + return self.app.get_data(self.ws_path) - def set_id(id): + def set_data(self, data): + self.app.set_data(self.ws_path, data) + + def is_online(self, userid): + data = self.get_data() + if data.get(userid): + return True + else: + return False + + def register(self, id): self.id = id + self.add_mine() - def get_ws(self, id): - self.get_data() - return self.data.get(id) + def add_mine(self): + data = self.get_data() + if data is None: + data = {} + data.update({self.id:self.ws}) + self.set_data(data) - def add_ws(self, ws): - if not self.id: + def delete_mine(self): + data = self.get_data() + if not data.get(self.id): return - - self.data = self.get_data() - if (self.data.get(self.id)): - return - self.data.update({self.id:ws}) - self.set_data() - - def delete_ws(self): - if not self.id: - return - - self.data = self.get_data() - if (not self.data.get(self.id)): - return - self.data = {k:v for k,v in self.data.items() if k != self.id } - self.set_data() + data = {k:v for k,v in self.data.items() if k != self.id } + self.set_data(data) + async def sendto(self, data, id=None): + if id is None: + return await ws_send(self.ws, data) + d = self.get_data() + ws = d.get(id) + return await ws_send(ws, data) + class WebsocketProcessor(PythonScriptProcessor): @classmethod def isMe(self,name): return name=='ws' - async def ws_sendstr(self, ws:web.WebSocketResponse, s:str): - data = { - "type":1, - "data":s - } - await ws.send_str(json.dumps(data)) - - def received_data_convert(self, data): - return data - async def path_call(self, request,params={}): await self.set_run_env(request) lenv = self.run_ns.copy() lenv.update(params) + params_kw = lenv.params_kw + userid = lenv.params_kw.userid or await lenv.get_user() + print(f'{params_kw=}, {userid=} ============') print(f'{request.path=}') del lenv['request'] txt = await self.loadScript(self.real_path) ws = web.WebSocketResponse() await ws.prepare(request) - ws_pool = WsPool(request.path, request.app) - await self.ws_sendstr(ws, 'Welcome to websock') + ws_pool = WsPool(ws, request.path, request.app) + # await self.ws_send(ws, 'Welcome to websock') async for msg in ws: if msg.type == aiohttp.WSMsgType.TEXT: - print('msg=:', msg.data) - lenv['ws_data'] = self.received_data_convert(msg.data) + if msg.data == 'exit': + break + lenv['ws_data'] = msg.data lenv['ws_pool'] = ws_pool exec(txt,lenv,lenv) func = lenv['myfunc'] resp = await func(request,**lenv) - await self.ws_sendstr(ws, resp) + # await self.ws_sendstr(ws, resp) elif msg.type == aiohttp.WSMsgType.ERROR: # print('ws connection closed with exception %s' % ws.exception()) - pass + break else: print('datatype error', msg.type) - # print('5----------------------------------') + ws_pool.delete_mine() self.retResponse = ws await ws.close() return ws