Spaces:
Sleeping
Sleeping
File size: 5,105 Bytes
d8d884a 4dd11c7 d8d884a 4dd11c7 d8d884a 4dd11c7 d8d884a 4dd11c7 d8d884a 4dd11c7 d8d884a 4dd11c7 d8d884a 4dd11c7 d8d884a 4dd11c7 d8d884a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
import coding
import scratchattach as scratch3
import threading
import time
import random
import os
global conn
global projectid
global endpoint
global users
projectid = os.getenv("ProjectID")
users = {}
session = scratch3.login(os.getenv("Username"), os.getenv("Password"))
class User:
def __init__(self, name, id):
self.last_request = time.time()
self.name = name
self.id = id
class Responder:
def __init__(self, projectid, channel, can_respond, can_stream, value, user):
user.last_request = time.time()
self.user = user
self.projectid = projectid
self.can_respond = can_respond
self.can_stream = can_stream
self.channel = channel
self.cooldown = time.time()
self.wrote = False
self.last_value = value
def poll(self):
value = scratch3.get_var(self.projectid, "channel "+str(self.channel))
if value != self.last_value and value != None:
self.user.last_request = time.time()
self.last_value = value
binary = coding.decimal_to_binary(int(value))
if binary[1:3]=="01":
value = str(coding.binary_to_decimal(binary[3:]))
if binary[1:3]=="10":
value = str("true" if binary[3:] == 1 else "false")
if binary[1:3]=="11":
value = coding.convert_to_text(binary[3:])
return value
def close(self):
if self.can_stream or not self.can_respond:
conn.set_var("channel "+str(self.channel), "0")
else:
while str(scratch3.get_var(self.projectid, "channel "+str(self.channel))) !="0":
pass
def respond(self, response):
global conn
if self.wrote and not self.can_stream:
raise Exception("Can't stream to this as a response")
if not (self.can_respond or self.can_stream):
raise Exception("Can't respond to this")
while time.time() - self.cooldown < 0.5:
time.sleep(0.5 - (time.time() - self.cooldown))
if self.can_respond or self.can_stream:
payload = "1"
if type(response) is int:
payload+="01"+coding.decimal_to_binary(response)
elif type(response) is bool:
payload+="10"+"1" if response else "0"
elif type(response) is str:
payload+="11"+coding.convert_to_binary(response)
self.last_value = str(coding.binary_to_decimal(payload))
conn.set_var("channel "+str(self.channel), str(coding.binary_to_decimal(payload)))
t= time.time()
times=0.2
while scratch3.get_var(self.projectid, "channel "+str(self.channel)) !=str(coding.binary_to_decimal(payload)):
if time.time()-t>=times:
print("Message not sent, retrying")
times+=0.1
conn.set_var("channel "+str(self.channel), str(coding.binary_to_decimal(payload)))
t=time.time()
self.wrote = True
class ConnectionEndpoint:
def receivedMessage(self, message, user, responder):
global users
r=random.randrange(1, 2047)
while r in users:
r=random.randrange(1, 2047)
users[r] = User(message, r)
responder.respond(r)
responder.close()
def thread(n):
global users
global conn
global projectid
global endpoint
conn.set_var("channel "+str(n), "0")
while True:
value = scratch3.get_var(projectid, "channel "+str(n))
if str(value) != "0" and value != None:
binary = coding.decimal_to_binary(int(value))
reqendpoint = coding.binary_to_decimal(binary[1:6])
header = coding.binary_to_decimal(binary[6:17])
staticpayload = binary[17] == '1'
streamingpayload = binary[18] == '1'
acceptstaticpayload = binary[19] == '1'
acceptstreamingpayload = binary[20] == '1'
payload = None
if staticpayload and not streamingpayload:
payloadformat = binary[21:23]
if payloadformat == "01":
payload = str(coding.binary_to_decimal(binary[23:]))
if payloadformat == "10":
payload = "true" if binary[23:]=='1' else "false"
if payloadformat == "11":
payload = coding.convert_to_text(binary[23:])
if header in users:
user = users[header]
else:
user = None
respond = Responder(projectid, n, acceptstaticpayload, acceptstreamingpayload, value, user)
endpoint[reqendpoint].receivedMessage(payload, user, respond)
def start_server(endpoints):
global conn
global endpoint
endpoints.insert(0, ConnectionEndpoint())
endpoint = endpoints
conn = session.connect_cloud(project_id)
threads = [threading.Thread(target=thread, args=(i+1,)) for i in range(10)]
for t in threads:
t.start()
return t |