Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 110 lines (91 sloc) 3.233 kB
5aef565 @zachwe first commit
zachwe authored
1 import socket, asyncore, json, eventlet
7d6d693 @sridatta Fixed up message types. Can interface with NowJS now
sridatta authored
2 import types
5aef565 @zachwe first commit
zachwe authored
3
4 #handle reading messages from the socket
5 class Handler(asyncore.dispatcher_with_send):
6 def __init__(self, host, server, port=None):
7 asyncore.dispatcher_with_send.__init__(self, host, port)
8 self.server = server
9
10 def handle_read(self):
11 data = self.recv(4096)
12 print data
13 if(data):
14 try:
15 data = json.loads(data)
7d6d693 @sridatta Fixed up message types. Can interface with NowJS now
sridatta authored
16 print data
17 name = data['type']
5aef565 @zachwe first commit
zachwe authored
18 if name == 'rfc':
7d6d693 @sridatta Fixed up message types. Can interface with NowJS now
sridatta authored
19 args = data['args']
20 f = self.server.funcs[data['fqn']]
21 fArgs = map(self.deserialize, args)
5aef565 @zachwe first commit
zachwe authored
22 f(*fArgs)
7d6d693 @sridatta Fixed up message types. Can interface with NowJS now
sridatta authored
23 elif name == 'closurecall':
24 args = data['args']
25 f = self.server.closures[data['fqn']]
26 fArgs = map(self.deserialize, args)
1c32a73 @zachwe fixed stuff
zachwe authored
27 f(*fArgs)
7d6d693 @sridatta Fixed up message types. Can interface with NowJS now
sridatta authored
28 elif name == 'new':
29 self.send(json.dumps({'type': 'functionList', 'functions': self.server.funcs.keys()}))
30 print "Node.js server connected"
1c32a73 @zachwe fixed stuff
zachwe authored
31
5aef565 @zachwe first commit
zachwe authored
32 except ValueError:
33 print 'not valid json'
34 except Exception as inst:
35 print inst
36 def handle_close(self):
37 self.close()
38
39 #deserialize function args to account for callbacks
7d6d693 @sridatta Fixed up message types. Can interface with NowJS now
sridatta authored
40 def deserialize(self, arg):
41 if type(arg) == types.DictType and 'fqn' in arg:
87c09e6 @sridatta Added TODO hints
sridatta authored
42 ''' TODO: Callbacks can accept callback. It accepts arguments naively here.
43 Remember to serialize any python functions and put them into a closures dictionary for later retrieval '''
7d6d693 @sridatta Fixed up message types. Can interface with NowJS now
sridatta authored
44 return lambda *x: self.send(json.dumps({'fqn': arg['fqn'], 'type': 'closurecall', 'args': map(self.server.createCb, x)}))
5aef565 @zachwe first commit
zachwe authored
45 else:
7d6d693 @sridatta Fixed up message types. Can interface with NowJS now
sridatta authored
46 return arg
5aef565 @zachwe first commit
zachwe authored
47
48 #listens for connections
49 class NowPyServer(asyncore.dispatcher):
50 def __init__(self, host, port):
51 asyncore.dispatcher.__init__(self)
52 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
53 self.set_reuse_addr()
54 self.bind((host, port))
55 self.listen(5)
56 self.funcs = {}
1c32a73 @zachwe fixed stuff
zachwe authored
57 self.closures = {}
5aef565 @zachwe first commit
zachwe authored
58
59 def handle_accept(self):
60 pair = self.accept()
61 if pair is None:
62 pass
63 else:
64 sock, addr = pair
65 if self.readable():
66 handler = Handler(sock, self)
7d6d693 @sridatta Fixed up message types. Can interface with NowJS now
sridatta authored
67 self.handler = handler
5aef565 @zachwe first commit
zachwe authored
68
69 def handle_close(self):
70 self.close();
71
72 #register function as one that can be sent over the wire
73 def register(self, name, f):
74 self.funcs[name] = f
1c32a73 @zachwe fixed stuff
zachwe authored
75
76 def createGroupFunction(self, group, fqn):
7d6d693 @sridatta Fixed up message types. Can interface with NowJS now
sridatta authored
77 return lambda *x: self.handler.send(json.dumps({'fqn': fqn, 'groupName': group, 'type': 'multicall', 'args': map(self.createCb, x)}))
1c32a73 @zachwe fixed stuff
zachwe authored
78
79
80 def createCb(self, arg):
81 if type(arg) == types.FunctionType:
7d6d693 @sridatta Fixed up message types. Can interface with NowJS now
sridatta authored
82 self.closures[arg.__name__] = arg
83 return {'fqn': arg.__name__}
5aef565 @zachwe first commit
zachwe authored
84
85 def runserver(self):
1c32a73 @zachwe fixed stuff
zachwe authored
86 asyncore.loop()
87c09e6 @sridatta Added TODO hints
sridatta authored
87
7d6d693 @sridatta Fixed up message types. Can interface with NowJS now
sridatta authored
88 server = NowPyServer('localhost', 8081)
89 def funcc(cb):
90 fn = server.createGroupFunction("everyone", "now.callMe")
91 fn(cb)
92
93 def funcb(s, cb):
5aef565 @zachwe first commit
zachwe authored
94 print s
95 try:
96 cb()
97 except Exception as inst:
98 print inst
7d6d693 @sridatta Fixed up message types. Can interface with NowJS now
sridatta authored
99
100 server.register('b', funcb)
101 server.register('c', funcc)
5aef565 @zachwe first commit
zachwe authored
102
103 print 'now listening'
104 server.runserver()
87c09e6 @sridatta Added TODO hints
sridatta authored
105
1c32a73 @zachwe fixed stuff
zachwe authored
106
87c09e6 @sridatta Added TODO hints
sridatta authored
107 ''' TODO: need some way of calling a node.js function from python.
108 The current way it is done in ruby-now is something like val = Now.createGroupFunction(group, fqn) which returns a function.
109 You can then call that function and it will do the rfc'''
Something went wrong with that request. Please try again.