Package: ldmud-asyncio
Python asynchronous I/O package for LDMudThis is a python module that enables the use of the Python asyncio module
with LDMud 3.6.2 and later. The module doesn't export any names, it just
extends the Python asyncio module to work with LDMud.UsageInstall from the python package indexThe efun package can be downloaded from the python package index:pip3 install --user ldmud-asyncioBuild & install the package yourselfYou can build the package yourself.First clone the repositorygit clone https://github.com/ldmud/python-asyncio.gitInstall the packagecd python-asyncio
python3 setup.py install --userAutomatically load the module at startupIn your Python startup script for LDMud add the following line:import ldmud_asyncioExamplescall_out() replacementimportldmud,ldmud_asyncio,asyncioasyncdefdo_call_out(cb,sec):awaitasyncio.sleep(sec)cb()defefun_call_out(cb:ldmud.Closure,sec:int)->None:asyncio.run(do_call_out(cb,sec))ldmud.register_efun("py_call_out",efun_call_out)Call a program and return the linesimportldmud,ldmud_asyncio,asyncioasyncdefdo_exec(prog,cb):proc=awaitasyncio.create_subprocess_exec(prog,stdout=asyncio.subprocess.PIPE)asyncforlineinproc.stdout:cb(line.decode())awaitproc.wait()cb(0)defefun_exec(prog:str,cb:ldmud.Closure)->None:asyncio.run(do_exec(prog,cb))ldmud.register_efun("py_exec",efun_exec)Start a websockets serverThis is the synchronization example from the websockets package.
Here we only added an efun to influence the value as well.This is the Python code:importldmud,ldmud_asyncio,asyncio,websockets,jsonSTATE={"value":0}USERS=set()defstate_event():returnjson.dumps({"type":"state",**STATE})defusers_event():returnjson.dumps({"type":"users","count":len(USERS)})asyncdefnotify_state():ifUSERS:# asyncio.wait doesn't accept an empty listmessage=state_event()awaitasyncio.wait([user.send(message)foruserinUSERS])asyncdefnotify_users():ifUSERS:# asyncio.wait doesn't accept an empty listmessage=users_event()awaitasyncio.wait([user.send(message)foruserinUSERS])asyncdefregister(websocket):USERS.add(websocket)awaitnotify_users()asyncdefunregister(websocket):USERS.remove(websocket)awaitnotify_users()asyncdefcounter(websocket,path):# register(websocket) sends user_event() to websocketawaitregister(websocket)try:awaitwebsocket.send(state_event())asyncformessageinwebsocket:data=json.loads(message)ifdata["action"]=="minus":STATE["value"]-=1awaitnotify_state()elifdata["action"]=="plus":STATE["value"]+=1awaitnotify_state()finally:awaitunregister(websocket)asyncio.run(websockets.serve(counter,"localhost",6789))asyncdefdo_ws_set_value(val):STATE["value"]=valawaitnotify_state()defefun_ws_set_value(val:int)->None:asyncio.run(do_ws_set_value(val))ldmud.register_efun("py_ws_set_value",efun_ws_set_value)And here the HTML code to run in the browser:<!DOCTYPE html><html><head><title>WebSocket demo</title><styletype="text/css">body{font-family:"Courier New",sans-serif;text-align:center;}.buttons{font-size:4em;display:flex;justify-content:center;}.button,.value{line-height:1;padding:2rem;margin:2rem;border:mediumsolid;min-height:1em;min-width:1em;}.button{cursor:pointer;user-select:none;}.minus{color:red;}.plus{color:green;}.value{min-width:2em;}.state{font-size:2em;}</style></head><body><divclass="buttons"><divclass="minus button">-</div><divclass="value">?</div><divclass="plus button">+</div></div><divclass="state"><spanclass="users">?</span>online</div><script>varminus=document.querySelector('.minus'),plus=document.querySelector('.plus'),value=document.querySelector('.value'),users=document.querySelector('.users'),websocket=newWebSocket("ws://127.0.0.1:6789/");minus.onclick=function(event){websocket.send(JSON.stringify({action:'minus'}));}plus.onclick=function(event){websocket.send(JSON.stringify({action:'plus'}));}websocket.onmessage=function(event){data=JSON.parse(event.data);switch(data.type){case'state':value.textContent=data.value;break;case'users':users.textContent=(data.count.toString()+" user"+(data.count==1?"":"s"));break;default:console.error("unsupported event",data);}};</script></body></html>Have fun!