안녕하세요, 나는 트위스트 jsonrpc 서버에 rpc 전화를 만드는 여러 마이크로 컨트롤러를 제공하기 위해 트위스트를 기반으로 rpc 서버를 개발하고 있습니다. 그러나 응용 프로그램은 또한 서버가 언제든지 각 마이크로에 정보를 보내도록 요구 했으므로 문제는 마이크로부터 원격 jsonrpc 호출의 응답을 서버 jsonrpc 요청과 혼동하지 않도록하는 좋은 방법 일 수 있습니다. 사용자.두 가지 방법을 구현하는 방법 jsonrpc + 트위스트 서버/클라이언트
결과는 소켓에서 오는 netstring/json 문자열이 이전 요구 사항의 응답인지 또는 서버의 새로운 요청인지 알 수 없으므로 마이크로가 잘못된 정보를 수신하고 있다는 것입니다. 당신은받는 사람이 그것을 해석하는 방법을 결정할 수 있도록 각 메시지에 충분한 정보를 추가 할 필요가
from twisted.internet import reactor
from txjsonrpc.netstring import jsonrpc
import weakref
creds = {'user1':'pass1','user2':'pass2','user3':'pass3'}
class arduinoRPC(jsonrpc.JSONRPC):
def connectionMade(self):
pass
def jsonrpc_identify(self,username,password,mac):
""" Each client must be authenticated just after to be connected calling this rpc """
if creds.has_key(username):
if creds[username] == password:
authenticated = True
else:
authenticated = False
else:
authenticated = False
if authenticated:
self.factory.clients.append(self)
self.factory.references[mac] = weakref.ref(self)
return {'results':'Authenticated as %s'%username,'error':None}
else:
self.transport.loseConnection()
def jsonrpc_sync_acq(self,data,f):
"""Save into django table data acquired from sensors and send ack to gateway"""
if not (self in self.factory.clients):
self.transport.loseConnection()
print f
return {'results':'synced %s records'%len(data),'error':'null'}
def connectionLost(self, reason):
""" mac address is searched and all reference to self.factory.clientes are erased """
for mac in self.factory.references.keys():
if self.factory.references[mac]() == self:
print 'Connection closed - Mac address: %s'%mac
del self.factory.references[mac]
self.factory.clients.remove(self)
class rpcfactory(jsonrpc.RPCFactory):
protocol = arduinoRPC
def __init__(self, maxLength=1024):
self.maxLength = maxLength
self.subHandlers = {}
self.clients = []
self.references = {}
""" Asynchronous remote calling to micros, simulating random calling from server """
import threading,time,random,netstring,json
class asyncGatewayCalls(threading.Thread):
def __init__(self,rpcfactory):
threading.Thread.__init__(self)
self.rpcfactory = rpcfactory
"""identifiers of each micro/client connected"""
self.remoteMacList = ['12:23:23:23:23:23:23','167:67:67:67:67:67:67','90:90:90:90:90:90:90']
def run(self):
while True:
time.sleep(10)
while True:
""" call to any of three potential micros connected """
mac = self.remoteMacList[random.randrange(0,len(self.remoteMacList))]
if self.rpcfactory.references.has_key(mac):
print 'Calling %s'%mac
proto = self.rpcfactory.references[mac]()
""" requesting echo from selected micro"""
dataToSend = netstring.encode(json.dumps({'method':'echo_from_micro','params':['plop']}))
proto.transport.write(dataToSend)
break
factory = rpcfactory(arduinoRPC)
"""start thread caller"""
r=asyncGatewayCalls(factory)
r.start()
reactor.listenTCP(7080, factory)
print "Micros remote RPC server started"
reactor.run()
예, 몇 시간 전에 스레드 API 설명서 (task.LoopingCall)를 읽은 후 동일한 결론을 내었습니다. 테스트를 거쳤고 꽤 잘 돌아갔다. 도움을 주셔서 감사합니다. – Jaime
jsonrpc 'id'필드가 어느 요청에 대한 응답인지 판단하기에 적합하지 않습니까? –
JSON-RPC 2.0 메시지를 명확하게 구분할 수 있습니다. 알림 - id 필드가없는 요청도 응답이 같지 않습니다 (결과 및 오류). –