syndicate-py/chat.py

80 lines
2.8 KiB
Python
Raw Normal View History

2018-11-20 19:45:27 +00:00
import sys
import asyncio
import random
import syndicate
from syndicate import patterns as P, actor
from syndicate.schema import simpleChatProtocol, gatekeeper, sturdy, dataspace
from syndicate.during import During
2018-11-20 19:45:27 +00:00
Present = simpleChatProtocol.Present
Says = simpleChatProtocol.Says
2018-11-20 19:45:27 +00:00
conn_str = '<ws "ws://localhost:8001/">'
cap_str = '<ref "syndicate" [] #[pkgN9TBmEd3Q04grVG4Zdw==]>'
cap = sturdy.SturdyRef.decode(syndicate.parse(cap_str))
# sys.stderr.write(
# 'Usage: chat.py [ <tcp "HOST" PORT> | <ws "ws://HOST[:PORT]/"> | <unix "PATH"> ]\n')
# sys.exit(1)
me = 'user_' + str(random.randint(10, 1000))
2018-11-20 19:45:27 +00:00
2019-06-13 11:59:05 +00:00
_print = print
def print(*items):
_print(*items)
sys.stdout.flush()
def main_facet(turn, root_facet, ds):
print('main_facet', ds)
f = turn._facet
turn.publish(ds, Present(me))
2021-08-19 17:26:12 +00:00
def on_presence(turn, who):
print('%s joined' % (who,))
return lambda turn: print('%s left' % (who,))
turn.publish(ds, dataspace.Observe(P.rec('Present', P.CAPTURE),
During(turn, on_add = on_presence).ref))
2021-08-19 17:26:12 +00:00
def on_says(turn, who, what):
print('%s says %r' % (who, what))
turn.publish(ds, dataspace.Observe(P.rec('Says', P.CAPTURE, P.CAPTURE),
During(turn, on_msg = on_says).ref))
2018-11-20 19:45:27 +00:00
2021-08-19 17:26:12 +00:00
async def accept_input():
reader = asyncio.StreamReader()
2021-08-19 18:06:33 +00:00
await actor.find_loop().connect_read_pipe(lambda: asyncio.StreamReaderProtocol(reader), sys.stdin)
while line := (await reader.readline()).decode('utf-8'):
2021-08-19 18:04:38 +00:00
actor.Turn.external(f, lambda turn: turn.send(ds, Says(me, line.strip())))
2021-08-19 18:06:33 +00:00
actor.Turn.external(f, lambda turn: turn.stop(root_facet))
2021-08-19 18:04:38 +00:00
turn.linked_task(accept_input())
2018-11-20 19:45:27 +00:00
def main(turn):
root_facet = turn._facet
def handle_gatekeeper(turn, gk):
turn.publish(gk.embeddedValue, gatekeeper.Resolve(cap, ds_receiver))
gk_receiver = During(turn, on_add = handle_gatekeeper).ref
def handle_ds(turn, ds):
return turn.facet(lambda turn: main_facet(turn, root_facet, ds.embeddedValue))
ds_receiver = During(turn, on_add = handle_ds).ref
2018-11-20 19:45:27 +00:00
disarm = turn.prevent_inert_check()
async def on_connected(tr):
disarm()
print('-'*50, 'Connected')
async def on_disconnected(tr, did_connect):
if did_connect:
print('-'*50, 'Disconnected')
else:
await asyncio.sleep(2)
return True
2018-11-20 19:45:27 +00:00
conn = syndicate.relay.TunnelRelay.from_str(turn,
conn_str,
gatekeeper_peer = gk_receiver,
on_connected = on_connected,
on_disconnected = on_disconnected)
2018-11-20 19:45:27 +00:00
actor.start_actor_system(main, name = 'chat', debug = False)