commodity_backingtrack_system/app/blockchain/server/zmq_server.py

158 lines
5.2 KiB
Python
Raw Normal View History

2021-03-11 13:09:43 +08:00
import datetime
import random
import zmq
import threading
import json
import os
import time
import blockchain as chain
_basepath = os.path.abspath(os.path.dirname(__file__))
conf = json.load(open(os.path.abspath(os.path.dirname(__file__)) + "\\config.json"))
lock = threading.Lock()
def build_msg(cmd, msg):
data = {
"cmd": cmd,
"msg": msg
}
return data
class ZmqServer(object):
def __init__(self):
self.server = conf["server"]
self.calc_port = conf["calc_port"]
self.add_port = conf["add_port"]
self.signal_port = conf["signal_port"]
self.client_num = conf["client_num"]
self.chain = chain.BlockChain()
print("服务器初始化的链id:%s" % id(self.chain))
self.ops_list = []
self.uncalc_ops = []
self.proof_list = []
def add_ops(self, option):
with lock:
self.ops_list.append(option)
def publish_calc_task(self):
while True:
self.uncalc_ops = list(self.ops_list)
print("未计算的缓存操作列表:%s"%self.uncalc_ops)
print("待计算的操作列表:%s"%self.ops_list)
if len(self.uncalc_ops) > 0:
thread = threading.Thread(target=self.publish_topic,
args=("calc_task", self.uncalc_ops, self.calc_port),
name="calc_task")
thread.start()
time.sleep(15)
def publish_add_task(self, proof):
pub_data = {
"data": list(self.uncalc_ops),
"proof": proof,
"index": len(self.chain.chain) + 1
}
print("即将发布新块:%s" % pub_data)
self.ops_list.clear()
self.chain.new_block(pub_data["data"], pub_data["proof"])
thread = threading.Thread(target=self.publish_topic, args=("add_task", pub_data, self.add_port),
name="add_task")
thread.start()
def check_proofs(self, proof):
with lock:
self.proof_list.append(proof)
temp = list(self.proof_list)
print("收到的证明列表:%s" % temp)
if len(temp) == self.client_num:
max_proof = max(temp, key=temp.count)
print("占大多数的证明:%s" % max_proof)
self.publish_add_task(proof)
self.proof_list.clear()
def publish_topic(self, topic, topic_data, port):
context = zmq.Context()
publisher = context.socket(zmq.PUB)
try:
publisher.bind("tcp://{}:{}".format(self.server, port))
print("publish_topicbind:[%s]:%s" % (self.server, port))
except zmq.ZMQError as e:
print("publish_topicbindfailed:[%s]:%s" % (e, port))
data_string = json.dumps(topic_data, sort_keys=True)
print("publish_topicsend:[%s]:%s" % (topic, data_string))
i = 0
while True:
publisher.send_multipart([bytes(topic, "utf-8"), bytes(data_string, 'utf-8')])
time.sleep(2)
i += 1
if i == 2:
print("publish_topicfinished")
break
publisher.close()
context.term()
def listen_msg(self):
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://{}:{}".format(self.server, self.signal_port))
while True:
message = socket.recv()
message_dict = json.loads(message)
print("Received: %s" % json.dumps(message_dict))
if message_dict["cmd"] == "new_proof":
self.check_proofs(message_dict["msg"])
response_string = json.dumps(build_msg("accept_proof", ""))
socket.send(bytes(response_string, encoding="utf-8"))
elif message_dict["cmd"] == "need_chain":
data_dict = build_msg("new_chain", self.chain.full_chain())
data_string = json.dumps(data_dict)
socket.send(bytes(data_string, encoding="utf-8"))
elif message_dict["cmd"] == "new_ops":
self.add_ops(message_dict["msg"])
response_string = json.dumps(build_msg("accept_ops", ""))
socket.send(bytes(response_string, encoding="utf-8"))
def add_fake_data(self):
while True:
data = (
{
"id": random.randint(0, 9),
"operator": "operator",
"option": "option",
"commodity": "commodity",
"time": get_current_time()
}
)
self.add_ops(data)
time.sleep(9)
def get_current_time(frm="%Y-%m-%d %H:%M:%S"):
dt = datetime.datetime.now()
return dt.strftime(frm)
if __name__ == '__main__':
server = ZmqServer()
# add_fake_thread = threading.Thread(target=server.add_fake_data, name="客户端消息监听")
# add_fake_thread.start()
publish_calc_task_thread = threading.Thread(target=server.publish_calc_task, name="客户端消息监听")
publish_calc_task_thread.start()
listen_thread = threading.Thread(target=server.listen_msg, name="客户端消息监听")
listen_thread.start()